【问题标题】:Mocking HttpClient in xunit for different endpoint在 xunit 中为不同的端点模拟 HttpClient
【发布时间】:2021-12-29 08:41:02
【问题描述】:

我正在嘲笑 HttpClient 以进行 this SO suggestion 之后的单元测试。它对单个端点按预期工作,我想知道如何针对不同的端点调整它。请参阅以下示例:

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 方法中两个端点的响应将相等。

【问题讨论】:

    标签: c# unit-testing mocking httpclient


    【解决方案1】:

    我认为您应该设置两个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();
    

    【讨论】:

      猜你喜欢
      • 2019-09-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多