Reputation: 788
I have the following test method. What I want to achieve in this test is to verify that the Error method was invoked by method SendSMSAsync()
when it received an exception.
[TestMethod]
public async Task SendSMSAsync_PostAsyncRequestResultedInAnException_LogExceptionAsAnError
{
_client.Setup(clnt => clnt.PostAsync("uri", It.IsAny<HttpContent>()))
.ThrowsAsync(new Exception("Exception!"));
var service = new SMSService();
_ = service.SendSMSAsync("mobile_number");
_logger.Verify(lgr => lgr.Error(exception => exception.Message.Contains("Exception!")))
}
This is the implementation of the service.
public async Task<bool> SendSMSAsync(string mobileNumber)
{
try
{
...
// Set up PostAsync to throw an exception.
using (var response = _client.PostAsync("uri", content))
{
...
}
}
catch(Exception exception)
{
_logger.Error(exception);
throw new Exception("An error has occurred while sending an SMS.");
}
}
If I run this, my test fails saying that the Test method threw an exception.
. Is there a way for me to verify if a method has been invoked inside the catch statement?
Upvotes: 0
Views: 142
Reputation: 219057
You could catch the exception as part of the test:
try
{
_ = service.SendSMSAsync("mobile_number");
}
catch
{
_logger.Verify(lgr => lgr.Error(exception => exception.Message.Contains("Exception!")));
}
To protect against false positives you might also return from the catch
and intentionally fail the test after the catch
. Something like:
try
{
_ = service.SendSMSAsync("mobile_number");
}
catch
{
_logger.Verify(lgr => lgr.Error(exception => exception.Message.Contains("Exception!")));
return;
}
throw new Exception("Test failed!");
The idea here is so the test doesn't "pass" if the method doesn't throw an exception in the first place.
Note that there may be tooling within the test framework to more gracefully fail a test, I don't recall off-hand. But the idea is generally the same.
Side note: Shouldn't there be an await
on that method call?
Upvotes: 3