调用PostAsync后测试HttpRequestMessage.Content的值

时间:2017-01-19 02:08:59

标签: asp.net .net asp.net-core httpclient .net-core

我们嘲笑了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);

1 个答案:

答案 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一次,因此如果您稍后尝试阅读它,它将为空。这就像海森堡的对象。