使用moq模拟HttpMessageHandler-如何获取请求的内容



在决定要返回什么样的响应进行测试之前,有没有办法获取http请求的内容?多个测试将使用这个类,每个测试将有多个http请求。

这段代码没有编译,因为lambda不是async,其中有一个await。我是异步等待的新手,所以我不知道如何解决这个问题。我曾短暂地考虑过拥有多个TestHttpClientFactory,但这意味着重复的代码,所以如果可能的话,我决定不使用它。

感谢您的帮助。

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方法而不是

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;
}
}

或者考虑创建自己的处理程序,公开委托以处理所需的行为。

例如

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;
}
}

最新更新