Search code examples
c#.net-corehttpclientmoqpolly

How to Mock HTTPClient from IHttpClientFactory combined with Polly policies in .NET Core using Moq


I create a HTTP Client using IHttpClientFactory and attach a Polly policy (requires Microsoft.Extensions.Http.Polly) as follows:

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");

How can I mock this HTTP Client using Moq?

EDIT: Mock means to be able to mock the requests of the HTTP. The policy should be applied as defined.


Solution

  • As described in many other posts on stackoverflow you don't mock the HTTP Client itself but 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)
        });
    

    To then in the end have a HTTP Client with the mocked HttpMessageHandler as well as the Polly Policy you can do the following:

    IServiceCollection services = new ServiceCollection();
    services.AddHttpClient("TestClient")
        .AddPolicyHandler(PollyPolicies.HttpResponsePolicies(arg1, arg2, arg3))
        .ConfigurePrimaryHttpMessageHandler(() => handlerMock.Object);
    
    HttpClient httpClient =
        services
            .BuildServiceProvider()
            .GetRequiredService<IHttpClientFactory>()
            .CreateClient("TestClient");