【问题标题】:xUnit mocked async test method not raise expected exeptionxUnit 模拟异步测试方法不会引发预期的异常
【发布时间】:2020-01-22 11:16:38
【问题描述】:

被测方法:

public Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, HttpCompletionOption option, CancellationToken cToken)
{
    if (request == null)
    {
        throw new ArgumentNullException(nameof(request));
    }

    // other logic

    return _client.SendAsync(request, option, cToken);
}

无法正常工作的测试:

[Fact]
public async Task SendAsync_ThrowExceptionOnNullRequest()
{
    var mockRestClient = new Mock<IRestClient>();
    mockRestClient.Setup(x => x.SendAsync(
        It.IsAny<HttpRequestMessage>(),
        It.IsAny<HttpCompletionOption>(),
        It.IsAny<CancellationToken>()))
        .Returns(Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK)));

    var excp = await Assert.ThrowsAnyAsync<ArgumentNullException>(
        async () => await mockRestClient.Object.SendAsync(
            null,
            HttpCompletionOption.ResponseHeadersRead,
            new CancellationToken(false)));

    Assert.NotNull(excp);
}

以及行为正确的测试:

[Fact]
public async Task SendAsync_ThrowExceptionOnNullRequest()
{         
    var restClient = new RestClient();

    await Assert.ThrowsAnyAsync<ArgumentNullException>(async () => await restClient.SendAsync(
        null,
        HttpCompletionOption.ResponseHeadersRead,
        new CancellationToken(false)));
}

所以,如果我不使用模拟此方法,我会得到预期的行为。 但是使用 mock(ed) 方法的测试不会以任何方式引发异常。

我应该如何模拟异步方法以正确测试?

谢谢。 附言

xUnit 2.4.1

.Net Core 2.1

【问题讨论】:

  • 你的系统在测试什么,可以分享一下吗?是RestClient 还是别的什么?
  • 自定义 RestClient - 标准 HttpClient 的包装器
  • 你已经有了答案,但这也是我的想法……你在嘲笑 SUT。

标签: async-await moq xunit


【解决方案1】:

您的错误测试设置了一个模拟以返回一个成功的响应,然后调用该模拟并期望它抛出。所以测试失败了,因为它设置了模拟返回一个成功的响应。

我应该如何模拟异步方法以正确测试?

不要模拟您正在测试的代码。如果你这样做,你只测试模拟框架,而不是你自己的代码。您正在测试的代码使用的模拟类型。这样您就可以测试自己的代码了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-10-30
    • 2014-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-01
    • 2014-05-21
    相关资源
    最近更新 更多