单元测试:如何从模拟接口异步 return 值

Unit Testing: How to return value asynchronously from mocked interface

我正在尝试对方法进行单元测试,并在调用处理 HttpClient 逻辑的模拟 'request provider' 时断言结果是特定类型的,尽管我已经设置了模拟接口它总是 returns空。

以前使用 HttpClient 时,我模拟了 HttpMessageHandler 并在另一端的方法中处理了业务逻辑,但是我们使用的第三方 API 需要多次调用它们的其余部分 api 使用 GET 请求,所以我想要一个解决方案,使解决方案更 'DRY'

以下是我目前正在尝试使用的设置

_requestProvider.Setup(
    svc => svc.GetAsync<PlayerBalance>(It.IsAny<string>(), It.IsAny<string>()))
    .Returns(() => Task.FromResult(new PlayerBalance
    {
        Balance = 0
    }));

_playerService = new PlayerService(_playerRepository.Object, 
            _secretsService.Object,
            _awsConfig,
            _requestProvider.Object);

我的act/assertion

var result = await _playerService.GetPlayerBalanceAsync(request);

result.Should().BeOfType<PlayerBalance>();

正在测试的方法

public async Task<PlayerBalance> GetPlayerBalanceAsync(PlayerBalanceRequest playerBalanceRequest)
{
    if (string.IsNullOrEmpty(playerBalanceRequest.Login)) throw new Exception("Login is a required parameter.");


    string url = $@"myrestendpoint";

    var result = await _requestProvider.GetAsync<List<PlayerBalance>>(url);

    return result.FirstOrDefault();
}

以及在 mock 上调用失败的地方

public async Task<TResult> GetAsync<TResult>(string uri, string token = "")
{
    HttpClient httpClient = CreateHttpClient(token);
    HttpResponseMessage response = await httpClient.GetAsync(uri);

    await HandleResponse(response);
    string serialized = await response.Content.ReadAsStringAsync();

    TResult result = await Task.Run(() =>
            JsonConvert.DeserializeObject<TResult>(serialized, _serializerSettings));

        return result;
}

当 运行 在 'Strict' 中时,它告诉我它需要调用但没有找到设置。我不太确定这里还需要设置什么。

最后一段代码返回的结果始终为空,但我希望它是 PlayerBalance { Balance = 0 }

如有任何帮助,我们将不胜感激。

澄清一下,我还通过以下方式尝试了我的设置

.Returns(Task.FromResult(new PlayerBalance
{
    Balance = 0
}));

.ReturnsAsync(new PlayerBalance {
    Balance = 0
});

你在嘲讽:

_requestProvider.GetAsync<PlayerBalance>(url)

什么时候应该嘲笑:

_requestProvider.GetAsync<List<PlayerBalance>>(url)

设置模拟以期望期望的行为:

_requestProvider.Setup(
        svc => svc.GetAsync<List<PlayerBalance>>(It.IsAny<string>(), It.IsAny<string>())
    )
    .ReturnsAsync(() => new List<PlayerBalance>() { new PlayerBalance
    {
        Balance = 0
    }});