如何验证是否为引发异常的类调用了方法

问题描述

我有以下测试方法。在此测试中,我想要实现的是验证Error方法在收到异常时是否由方法SendSMSAsync()调用

[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!")))
}

这是服务的实现。

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.");
    }
}

如果运行此命令,则测试失败,提示Test method threw an exception.。我可以通过一种方法来验证是否在catch语句内调用一个方法吗?

解决方法

您可以在测试中捕获异常:

try
{
    _ = service.SendSMSAsync("mobile_number");
}
catch
{
    _logger.Verify(lgr => lgr.Error(exception => exception.Message.Contains("Exception!")));
}

为了防止误报,您还可以从catch返回,并故意在catch之后通过测试。像这样:

try
{
    _ = service.SendSMSAsync("mobile_number");
}
catch
{
    _logger.Verify(lgr => lgr.Error(exception => exception.Message.Contains("Exception!")));
    return;
}
throw new Exception("Test failed!");

这里的想法是,如果该方法首先没有引发异常,则测试不会“通过”。

请注意,测试框架中可能存在一些工具,可以更正常地使测试失败,但我不会立即回忆起。但想法通常是相同的。


旁注:该方法调用上不应该有await吗?