xUnit 模拟异步测试方法未引发预期的异常

xUnit mocked async test method not raise expected exeption

被测方法:

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) 方法的测试不会以任何方式引发异常。

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

谢谢。 PS

xUnit 2.4.1

.网络核心 2.1

你不正确的测试是设置一个 mock 来 return 一个成功的响应,然后调用那个 mock 期望它抛出。所以测试失败了,因为它将模拟设置为 return 成功响应。

How I should mock async method for test correctly?

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