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);
}
7 Answers, 1 is accepted
You need to "await" all Tasks in the chain for the exception to be rethrown to the caller.
Regards,
Stefan
Telerik
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){}
}
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
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
This works,
Thanks
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
