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