如何解决从扩展HttpClient的类中使用GetAsync时,该如何模拟它?
我已经阅读了一些有关模拟HttpClient的知识,并且发现了几个问题,例如this one或this one,这些问题都表明,当我们要模拟HttpClient方法(例如GetAsync)时,我们必须改为模拟由所有HttpClient方法调用的SendAsync,如下所示:
Mock<HttpMessageHandler> _clientMock = new Mock<HttpMessageHandler>(MockBehavior.Strict);
_clientMock.Protected().Setup<Task<HttpResponseMessage>>("SendAsync",ItExpr.IsAny<HttpRequestMessage>(),ItExpr.IsAny<CancellationToken>())
.Returns(Task.Fromresult(someResponse)).Verifiable();
var x = httpClient.GetAsync("someURL");
_clientMock.Protected().Verify(
"SendAsync",Times.Exactly(1),ItExpr.Is<HttpRequestMessage>(req => req.Method == HttpMethod.Get && req.RequestUri == new Uri("someURL")),ItExpr.IsAny<CancellationToken>()
);
这很好用,并且如果我完全像这样运行测试,显然可以通过。
但是,我正在测试的方法如下:
public async Task<Response<IEnumerable<Instance>>> GetInstancesAsync(string accesstoken,bool? enable = null)
{
try
{
using (var client = new Client(this._baseUrl,accesstoken))
{
var url = string.Format("configurations/instances?enable={0}",enable);
// Creates a request and returns the result
HttpResponseMessage response = await client.GetAsync(url).ConfigureAwait(false);
return await response.Content.ReadAsAsync<Response<IEnumerable<Instance>>>().ConfigureAwait(false);
}
}
catch { }
return null;
}
如您所见,它使用Client,这是我们创建的类,并且扩展了HttpClient,我认为问题可能出在这里。当我尝试测试此方法时,上述解决方案不起作用,并且从未调用过SendAsync。我不明白为什么。
我的单元测试当前看起来像这样:
_messageHandlerMock.Protected().Setup<Task<HttpResponseMessage>>("SendAsync",ItExpr.IsAny<CancellationToken>())
.Returns(Task.Fromresult(responseMessage)).Verifiable();
var result = await _configurationsproxy.GetInstancesAsync(ACCESS_TOKEN,true);
Assert.IsNotNull(result);
_messageHandlerMock.Protected().Verify(
"SendAsync",ItExpr.Is<HttpRequestMessage>(req => req.Method == HttpMethod.Get && req.RequestUri == new Uri(url)),ItExpr.IsAny<CancellationToken>()
);
第_messageHandlerMock.Protected().Verify(...)
行失败,导致
Moq.MockException: 预期对模拟的调用恰好是1次,但是是0次”,并且Assert.IsNotNull(result)也失败,结果为null。
解决方法
那么我将在此处发布正式答案。很高兴!
您不在任何地方的新Client(...)中使用_messageHandlerMock,因此它使用自己的内部版本而不是您创建的模拟。因此,它绕过了您的模拟检查。它最终在Client类中更新了自己的实例。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。