gpt4 book ai didi

c# - 使用多个请求模拟 HttpClient

转载 作者:行者123 更新时间:2023-12-05 01:00:25 25 4
gpt4 key购买 nike

我正在尝试对调用 API 的函数进行单元测试。我已经使用模拟 HttpMessageHandler 成功地做到了这一点如下所示,它允许我伪造来自 API 的响应:

private static Mock<HttpMessageHandler> GetMockHttpMessageHandler(string mockResponse)
{
var mockMessageHandler = new Mock<HttpMessageHandler>();
mockMessageHandler.Protected()
.Setup<Task<HttpResponseMessage>>("SendAsync", ItExpr.IsAny<HttpRequestMessage>(), ItExpr.IsAny<CancellationToken>())
.Returns(Task.FromResult(new HttpResponseMessage
{
StatusCode = HttpStatusCode.OK,
Content = new StringContent(mockResponse)
}));
return mockMessageHandler;
}

到目前为止,一切都很好。我已经能够测试我的功能的一半,下半部分进行另一个 api 调用 - 然后两个响应都被包装到系统使用的对象中。问题是,第二个 api 需要有不同的模拟响应。

我以为我可以更改 ItExpr.IsAny<HttpRequestMessage>()在上面的代码中到new HttpRequestMessage(HttpMethod.Post, "http://LiveUrl.com/AuthenticateUserCredential")然后有多个 Setup/Returns响应根据 URI 变化,但我尝试如下(只有一个 Setup/Return 来测试我没有破坏前半部分测试)

private static Mock<HttpMessageHandler> GetMockHttpMessageHandler(string mockResponse)
{
var mockMessageHandler = new Mock<HttpMessageHandler>();
mockMessageHandler.Protected()
.Setup<Task<HttpResponseMessage>>("SendAsync", new HttpRequestMessage(HttpMethod.Post, "http://LiveUrl.com/AuthenticateUserCredential"), ItExpr.IsAny<CancellationToken>())
.Returns(Task.FromResult(new HttpResponseMessage
{
StatusCode = HttpStatusCode.OK,
Content = new StringContent(mockResponse)
}));

return mockMessageHandler;
}

现在以上中断了第一个 api 调用 - 我得到以下响应:

handler did not return a response message

现在我被困住了 - 我正在尝试做的事情是否可能?

最佳答案

认为在 Moq 中使用 SetupSequence 可以解决这个问题:

private HttpClient GetHttpClientWithHttpMessageHandlerSequenceResponseMock(List<Tuple<HttpStatusCode,HttpContent>> returns)
{

var handlerMock = new Mock<HttpMessageHandler>(MockBehavior.Strict);
var handlerPart = handlerMock
.Protected()
// Setup the PROTECTED method to mock
.SetupSequence<Task<HttpResponseMessage>>(
"SendAsync",
ItExpr.IsAny<HttpRequestMessage>(),
ItExpr.IsAny<CancellationToken>()
);

foreach (var item in returns)
{
handlerPart = AddReturnPart(handlerPart,item.Item1,item.Item2);
}
handlerMock.Verify();
// use real http client with mocked handler here
var httpClient = new HttpClient(handlerMock.Object)
{
BaseAddress = new Uri("http://test.com/"),
};
return httpClient;
}

private Moq.Language.ISetupSequentialResult<Task<HttpResponseMessage>> AdddReturnPart(Moq.Language.ISetupSequentialResult<Task<HttpResponseMessage>> handlerPart,
HttpStatusCode statusCode, HttpContent content)
{
return handlerPart

// prepare the expected response of the mocked http call
.ReturnsAsync(new HttpResponseMessage()
{
StatusCode = statusCode, // HttpStatusCode.Unauthorized,
Content = content //new StringContent("[{'id':1,'value':'1'}]"),
});
}

调用上面的代码:

public void ExceuteMultipleHttpCalls()
{
var contentSequence1 = new StringContent("{ 'id':'anId','email':'test@valid.com'}", Encoding.UTF8, "application/json");
var contentSequence2 = new StringContent("{ 'id':'anotherId','email':'anotherTest@valid.com'}", Encoding.UTF8, "application/json");

var sequenceResponse = new List<Tuple<HttpStatusCode, HttpContent>>
{
new Tuple<HttpStatusCode, HttpContent>(HttpStatusCode.OK, contentSequence1),
new Tuple<HttpStatusCode, HttpContent>(HttpStatusCode.Created, contentSequence2)
};

HttpClient httpClient = GetHttpClientWithHttpMessageHandlerSequenceResponseMock(sequenceResponse);
//use this httpClient to call function where this client is called multiple times.

}

关于c# - 使用多个请求模拟 HttpClient,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49956455/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com