We've mocked the HttpMessageHandler
, so we can test a class that uses the HttpClient
.
One of our methods under test creates a new HttpClient
, calls PostAsync
, and disposes the HttpClient
. We would like to test the Content
of the HTTP request like this:
Assert.Equal("", ActualHttpRequestMessage.Content.ReadAsStringAsync());
The problem is that we "Cannot access a disposed object," because the HttpClient
disposes the Content
.
Question How can we inspect the content?
This is our Moq setup.
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)
}));
This is how we are using it in the class under test.
new HttpClient(HttpMessageHandler);
Change your mock to this:
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)
}));
Then you can test like this:
Assert.Equal("", ActualHttpRequestContent);
Keep in mind that we can only read Content
once, so if you try to read it later, it will be empty. It's like a Heisenberg object.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With