Expected Exception with async methods

8 posts, 0 answers
  1. Vikas
    Vikas avatar
    36 posts
    Member since:
    Dec 2015

    Posted 21 Jan Link to this post

    I have a async method under test and this method calls a rest service asynchronously, I want to test that if the rest service call returns an error then this method under test throws it back, I am guessing because of the way the exception are wrapped in a Task it is not working for me.

    If i debug I can see that service.restcall does throw the exception with "Test" but the test method never receives the error.

    public async Task CreateDatastore()

    {

    await service.restcall()

    }

     -------------- Test code -----------------

    [TestMethod]
            [ExpectedException(typeof(Exception), "Test")] 

    public void Should_Throw_Back_The_RestException()
            {
                //Arrange
                var service = Mock.Create<IRestApiServices>();
                var viewModel = new CreateViewModel(service);
                var privViewModel = new PrivateAccessor(viewModel);

                var ex = new Exception("Test");

                Mock.Arrange(() => service.restcall().IgnoreArguments().throws(ex).MustBeCalled();

                //Act            
                privViewModel.CallMethod("Methodundertest", null);

                //Assert
                Mock.Assert(service);
            }

  2. Stefan
    Admin
    Stefan avatar
    198 posts

    Posted 26 Jan Link to this post

    Hello Vikas,

    You need to "await" all Tasks in the chain for the exception to be rethrown to the caller.

    Regards,
    Stefan
    Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
  3. DevCraft R3 2016 release webinar banner
  4. Vikas
    Vikas avatar
    36 posts
    Member since:
    Dec 2015

    Posted 27 Jan in reply to Stefan Link to this post

    Not sure I understand, I am awaiting on all the async calls in my real code. so this is my method under test. When I arrange this method and tell it throw an error and run my test the call to service.restcall() throws the error and it goes into the catch block.

    What i am expecting is that if remove the try/catch then my unit test should get that same error.

    Please note that the method under test is private method i am calling it from my unit test using private accessor

    privViewModel.CallMethod("restcall", null);

    Mock.Assert(service);

    private async Task CreateDatastore()
    {

    try{
    await service.restcall()

    }catch (Exception ex){}
    }

  5. Stefan
    Admin
    Stefan avatar
    198 posts

    Posted 29 Jan Link to this post

    Hello Vikas,

    Exceptions thrown in async methods are wrapped by the returned Task. So, I guess in your code you need to change to the following:
    await privViewModel.CallMethod("CreateDatastore") as Task;


    Regards,
    Stefan
    Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
  6. Vikas
    Vikas avatar
    36 posts
    Member since:
    Dec 2015

    Posted 01 Feb in reply to Stefan Link to this post

    I cannot do that callmethod is not a async method
  7. Kaloyan
    Admin
    Kaloyan avatar
    872 posts

    Posted 04 Feb Link to this post

    Hi Vikas,

    Here is a sample that works:
    public class ClassWithNonPublicMembers
    {
        private async Task<int> MePrivate()
        {
            return 1000;
        }
    }
     
    [TestMethod]
    public async Task ShouldAwaitPrivateMethod()
    {
        // ARRANGE
        var mockedClass = Mock.Create<ClassWithNonPublicMembers>(Behavior.CallOriginal);
     
        // ACT
        var inst = new PrivateAccessor(mockedClass);
        var actual = await ((Task<int>)inst.CallMethod("MePrivate"));
     
        // ASSERT
        Assert.AreEqual(1000, actual);
    }

    Please, note that it is mandatory for the test method to be an async Task as well.

    Regards,
    Kaloyan
    Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
  8. Vikas
    Vikas avatar
    36 posts
    Member since:
    Dec 2015

    Posted 08 Feb in reply to Kaloyan Link to this post

    This works,

     

    Thanks

  9. Kaloyan
    Admin
    Kaloyan avatar
    872 posts

    Posted 09 Feb Link to this post

    Hello Vikas,

    I am happy to hear that.

    Please, let me know if you will require further assistance. We will be happy to help again.

    Regards,
    Kaloyan
    Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
Back to Top
DevCraft R3 2016 release webinar banner