单元测试:如何从模拟接口异步 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
}});
我正在尝试对方法进行单元测试,并在调用处理 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
}});