如何使用 Moq 从 IHttpClientFactory 模拟 HTTPClient 并结合 .NET Core 中的 Polly 策略

Posted

技术标签:

【中文标题】如何使用 Moq 从 IHttpClientFactory 模拟 HTTPClient 并结合 .NET Core 中的 Polly 策略【英文标题】:How to Mock HTTPClient from IHttpClientFactory combined with Polly policies in .NET Core using Moq 【发布时间】:2021-11-12 16:10:37 【问题描述】:

我使用 IHttpClientFactory 创建一个 HTTP 客户端并附加 Polly 策略(需要 Microsoft.Extensions.Http.Polly),如下所示:

using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.DependencyInjection;

IHost host = new HostBuilder()
    .ConfigureServices((hostingContext, services) =>
    
        services.AddHttpClient("TestClient", client =>
        
            client.DefaultRequestHeaders.Add("Authorization", $"Bearer accessToken");
            client.DefaultRequestHeaders.Accept.Clear();
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        )
        .AddPolicyHandler(PollyPolicies.HttpResponsePolicies(
            arg1, 
            arg2,
            arg3));
    )
    .Build();

IHttpClientFactory httpClientFactory = host.Services.GetRequiredService<IHttpClientFactory>();

HttpClient httpClient = httpClientFactory.CreateClient("TestClient");

如何使用 Moq 模拟这个 HTTP 客户端?

编辑:模拟意味着能够模拟 HTTP 的请求。应按定义应用该政策。

【问题讨论】:

你想测试什么?是否要测试该策略? 好的,现在很清楚了。如果您想测试 polly,那么我建议将其作为集成测试进行,正如我在 here 中描述的那样。 【参考方案1】:

正如在 *** 上的许多其他帖子中所述,您不会模拟 HTTP 客户端本身,而是模拟 HttpMessageHandler:

Mock<HttpMessageHandler> handlerMock = new Mock<HttpMessageHandler>(MockBehavior.Strict);
handlerMock
    .Protected()
    .Setup<Task<HttpResponseMessage>>(
        "SendAsync",
        ItExpr.IsAny<HttpRequestMessage>(),
        ItExpr.IsAny<CancellationToken>()
    )
    .ReturnsAsync(new HttpResponseMessage()
    
        StatusCode = HttpStatusCode.OK,
        Content = new StringContent(response)
    );

到最后拥有一个带有模拟 HttpMessageHandler 以及 Polly 策略的 HTTP 客户端,您可以执行以下操作:

IServiceCollection services = new ServiceCollection();
services.AddHttpClient("TestClient")
    .AddPolicyHandler(PollyPolicies.HttpResponsePolicies(arg1, arg2, arg3))
    .ConfigurePrimaryHttpMessageHandler(() => handlerMock.Object);

HttpClient httpClient =
    services
        .BuildServiceProvider()
        .GetRequiredService<IHttpClientFactory>()
        .CreateClient("TestClient");

【讨论】:

以上是关于如何使用 Moq 从 IHttpClientFactory 模拟 HTTPClient 并结合 .NET Core 中的 Polly 策略的主要内容,如果未能解决你的问题,请参考以下文章

如何使用MOQ进行单元测试

如何使用 MOQ 框架在 c# 中模拟静态方法?

如何使用 moq 模拟 ConfigurationManager.AppSettings

如何使用 Moq 为不同的参数设置两次方法

如何使用moq生成假数据进行单元测试?

如何使用 Moq 框架模拟 ModelState.IsValid?