用moq模拟HttpMessageHandler-如何获取请求的内容? [英] Mocking HttpMessageHandler with moq - How do I get the contents of the request?

查看:77
本文介绍了用moq模拟HttpMessageHandler-如何获取请求的内容?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在决定要发送回测试的哪种响应之前,有没有办法获取http请求的内容?多个测试将使用此类,并且每个测试将具有多个http请求.这段代码无法编译,因为lambda不是异步的,并且其中有一个等待.我是异步等待的新手,所以不确定如何解决此问题.我曾短暂考虑过拥有多个TestHttpClientFactories,但这意味着重复的代码,因此,如果可能的话,请反对使用它.感谢您的帮助.

Is there a way to get the contents of the http request before deciding what kind of response I want to send back for the test? Multiple tests will use this class and each test will have multiple http requests. This code does not compile because the lambda is not async and there is an await in it. I'm new to async-await, so I'm not sure how to resolve this. I briefly considered having multiple TestHttpClientFactories, but that would mean duplicated code, so decided against it, if possible. Any help is appreciated.

public class TestHttpClientFactory : IHttpClientFactory
{
    public HttpClient CreateClient(string name)
    {
        var messageHandlerMock = new Mock<HttpMessageHandler>(MockBehavior.Strict);

        messageHandlerMock.Protected()
            .Setup<Task<HttpResponseMessage>>("SendAsync", ItExpr.IsAny<HttpRequestMessage>(), ItExpr.IsAny<CancellationToken>())
            .ReturnsAsync((HttpRequestMessage request, CancellationToken token) =>
            {
                HttpResponseMessage response = new HttpResponseMessage();
                var requestMessageContent = await request.Content.ReadAsStringAsync();

                // decide what to put in the response after looking at the contents of the request

                return response;
            })
            .Verifiable();

        var httpClient = new HttpClient(messageHandlerMock.Object);
        return httpClient;
    }
}

推荐答案

要利用异步委托,请改用 Returns 方法

To take advantage of the async delegate use the Returns method instead

public class TestHttpClientFactory : IHttpClientFactory {
    public HttpClient CreateClient(string name) {
        var messageHandlerMock = new Mock<HttpMessageHandler>(MockBehavior.Strict);

        messageHandlerMock.Protected()
            .Setup<Task<HttpResponseMessage>>("SendAsync", ItExpr.IsAny<HttpRequestMessage>(), ItExpr.IsAny<CancellationToken>())
            .Returns(async (HttpRequestMessage request, CancellationToken token) => {
                
                string requestMessageContent = await request.Content.ReadAsStringAsync();

                HttpResponseMessage response = new HttpResponseMessage();

                //...decide what to put in the response after looking at the contents of the request

                return response;
            })
            .Verifiable();

        var httpClient = new HttpClient(messageHandlerMock.Object);
        return httpClient;
    }
}

或者考虑创建自己的处理程序,该处理程序公开一个委托来处理所需的行为.

Or consider creating your own handler that exposes a delegate to handle the desired behavior.

例如

public class DelegatingHandlerStub : DelegatingHandler {
    private readonly Func<HttpRequestMessage, CancellationToken, Task<HttpResponseMessage>> _handlerFunc;
    public DelegatingHandlerStub() {
        _handlerFunc = (request, cancellationToken) => Task.FromResult(request.CreateResponse(HttpStatusCode.OK));
    }

    public DelegatingHandlerStub(Func<HttpRequestMessage, CancellationToken, Task<HttpResponseMessage>> handlerFunc) {
        _handlerFunc = handlerFunc;
    }

    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) {
        return _handlerFunc(request, cancellationToken);
    }
}

像这样在工厂中使用

public class TestHttpClientFactory : IHttpClientFactory {
    public HttpClient CreateClient(string name) {
        var messageHandlerMock = new DelegatingHandlerStub(async (HttpRequestMessage request, CancellationToken token) => {
                
            string requestMessageContent = await request.Content.ReadAsStringAsync();

            HttpResponseMessage response = new HttpResponseMessage();

            //...decide what to put in the response after looking at the contents of the request

            return response;
        });

        var httpClient = new HttpClient(messageHandlerMock);
        return httpClient;
    }
}

这篇关于用moq模拟HttpMessageHandler-如何获取请求的内容?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆