在 xunit 中为不同端点模拟 HttpClient
Mocking HttpClient in xunit for different endpoint
我正在嘲笑 HttpClient
在 之后进行单元测试。对于单个端点,它按预期工作,我想知道如何针对不同的端点调整它。请参阅以下示例:
class Agent
{
private HttpClient _client;
private string _baseUri = "http://example.com/";
public Agent(HttpClient client)
{ _client = client; }
public bool Run()
{
var res1 = client.GetAsync(new Uri(_baseUri, "endpoint1"));
var res2 = client.GetAsync(new Uri(_baseUri, "endpoint2"));
return res1 == res2
}
}
// In the test method:
var responseMessage = new HttpResponseMessage
{
StatusCode = HttpStatusCode.OK,
Content = new StringContent("test_return")
};
var mock = new Mock<HttpMessageHandler>();
mock.Protected()
.Setup<Task<HttpResponseMessage>>(
"SendAsync",
ItExpr.IsAny<HttpRequestMessage>(),
ItExpr.IsAny<CancellationToken>())
.ReturnsAsync(responseMessage);
client = new HttpClient(mock.Object);
var agent = new Agent(client);
var resp = agent.Run();
Assert.True(resp)
在上面的示例中,resp
将始终是 true
,因为作为模拟的结果,Run
方法中两个端点的响应将相等。
我认为您应该设置两个 SendAsync
调用,如下所示。
// response to /endpoint1
var responseMessage1 = new HttpResponseMessage
{
StatusCode = HttpStatusCode.OK,
Content = new StringContent("test_return")
};
// response to /endpoint2
var responseMessage2 = new HttpResponseMessage
{
StatusCode = HttpStatusCode.OK,
Content = new StringContent("test_other_return")
};
var mock = new Mock<HttpMessageHandler>();
// mock a call to /endpoint1
mock.Protected()
.Setup<Task<HttpResponseMessage>>(
"SendAsync",
ItExpr.Is<HttpRequestMessage>(
m => m.RequestUri.AbsolutePath.Contains(
"endpoint1")),
ItExpr.IsAny<CancellationToken>())
.ReturnsAsync(responseMessage1);
// mock a call to /endpoint2
mock.Protected()
.Setup<Task<HttpResponseMessage>>(
"SendAsync",
ItExpr.Is<HttpRequestMessage>(
m => m.RequestUri.AbsolutePath.Contains(
"endpoint2")),
ItExpr.IsAny<CancellationToken>())
.ReturnsAsync(responseMessage2);
var client = new HttpClient(mock.Object);
var agent = new Agent(client);
var resp = agent.Run();
我正在嘲笑 HttpClient
在
class Agent
{
private HttpClient _client;
private string _baseUri = "http://example.com/";
public Agent(HttpClient client)
{ _client = client; }
public bool Run()
{
var res1 = client.GetAsync(new Uri(_baseUri, "endpoint1"));
var res2 = client.GetAsync(new Uri(_baseUri, "endpoint2"));
return res1 == res2
}
}
// In the test method:
var responseMessage = new HttpResponseMessage
{
StatusCode = HttpStatusCode.OK,
Content = new StringContent("test_return")
};
var mock = new Mock<HttpMessageHandler>();
mock.Protected()
.Setup<Task<HttpResponseMessage>>(
"SendAsync",
ItExpr.IsAny<HttpRequestMessage>(),
ItExpr.IsAny<CancellationToken>())
.ReturnsAsync(responseMessage);
client = new HttpClient(mock.Object);
var agent = new Agent(client);
var resp = agent.Run();
Assert.True(resp)
在上面的示例中,resp
将始终是 true
,因为作为模拟的结果,Run
方法中两个端点的响应将相等。
我认为您应该设置两个 SendAsync
调用,如下所示。
// response to /endpoint1
var responseMessage1 = new HttpResponseMessage
{
StatusCode = HttpStatusCode.OK,
Content = new StringContent("test_return")
};
// response to /endpoint2
var responseMessage2 = new HttpResponseMessage
{
StatusCode = HttpStatusCode.OK,
Content = new StringContent("test_other_return")
};
var mock = new Mock<HttpMessageHandler>();
// mock a call to /endpoint1
mock.Protected()
.Setup<Task<HttpResponseMessage>>(
"SendAsync",
ItExpr.Is<HttpRequestMessage>(
m => m.RequestUri.AbsolutePath.Contains(
"endpoint1")),
ItExpr.IsAny<CancellationToken>())
.ReturnsAsync(responseMessage1);
// mock a call to /endpoint2
mock.Protected()
.Setup<Task<HttpResponseMessage>>(
"SendAsync",
ItExpr.Is<HttpRequestMessage>(
m => m.RequestUri.AbsolutePath.Contains(
"endpoint2")),
ItExpr.IsAny<CancellationToken>())
.ReturnsAsync(responseMessage2);
var client = new HttpClient(mock.Object);
var agent = new Agent(client);
var resp = agent.Run();