我们嘲笑了HttpMessageHandler
,因此我们可以测试使用HttpClient
的类。
我们测试的其中一种方法会创建一个新的HttpClient
,调用PostAsync
,并处置HttpClient
。我们想测试HTTP请求的Content
,如下所示:
Assert.Equal("", ActualHttpRequestMessage.Content.ReadAsStringAsync());
问题是我们“无法访问已处置的对象”,因为the HttpClient
disposes the Content
。
问题我们如何检查内容?
这是我们的Moq设置。
MockHttpMessageHandler = new Mock<HttpMessageHandler>();
MockHttpMessageHandler
.Protected()
.Setup<Task<HttpResponseMessage>>(
"SendAsync",
ItExpr.IsAny<HttpRequestMessage>(),
ItExpr.IsAny<CancellationToken>())
.Callback<HttpRequestMessage, CancellationToken>(
(httpRequestMessage, cancellationToken) =>
{
ActualHttpRequestMessage = httpRequestMessage;
})
.Returns(
Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StringContent(string.Empty)
}));
这就是我们在被测试的课程中使用它的方式。
new HttpClient(HttpMessageHandler);
答案 0 :(得分:3)
将模拟更改为:
MockHttpMessageHandler
.Protected()
.Setup<Task<HttpResponseMessage>>(
"SendAsync",
ItExpr.IsAny<HttpRequestMessage>(),
ItExpr.IsAny<CancellationToken>())
.Callback<HttpRequestMessage, CancellationToken>(
(httpRequestMessage, cancellationToken) =>
{
// +++++++++++++++++++++++++++++++++++++++++
// Read the Content here before it's disposed
ActualHttpRequestContent = httpRequestMessage.Content
.ReadAsStringAsync()
.GetAwaiter()
.GetResult();
ActualHttpRequestMessage = httpRequestMessage;
})
.Returns(
Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StringContent(string.Empty)
}));
然后你可以这样测试:
Assert.Equal("", ActualHttpRequestContent);
请注意,我们只能阅读Content
一次,因此如果您稍后尝试阅读它,它将为空。这就像海森堡的对象。