Home > Back-end >  Mock http client that is set up inside of Program.cs
Mock http client that is set up inside of Program.cs

Time:01-07

I have a typed httpclient that I am injecting in my application using the HttpClientFactory extension methods for services in Program.cs

My client looks something like this with the HttpClient injected via the constructor:

public class MyClient
{
    private readonly HttpClient _httpClient;
    public MyClient(HttpClient httpClient)
    {
        _httpClient = httpClient;
    }

    public async Task<string> GetStuffFromApi()
    {
        // method to get content from API
        // return stuff
    }
}

The relevant section in Program.cs looks something like this for example:

        services.AddHttpClient<IMyClient, MyClient>(client =>
        {
            client.BaseAddress = new Uri("https://somewebsite.com/api");
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/plain"));
        }).AddPolicyHandler(MyClientPolicies.GetRetryAsyncPolicy());

I would like to test the retry policy among other things for this client. I found a great mockhttp library that is helpful for the mock client setup (MockHttp), but I am unsure of exactly what I need to do in order to include the retry policy behavior in my mocked client.

So the test looks something like this using XUnit currently:

public class MyClientTests
{
    [Fact]
    public async Task MyClient_RetriesRequest_OnTransientErrors()
    {
        // Arrange
        var mockHttp = new MockHttpMessageHandler();
        mockHttp.When("*").Respond(HttpStatusCode.RequestTimeout);
        var mockClient = new MyClient(mockHttp.ToHttpClient());
        // Act
        // ... call the method
        // Assert
        // ... assert the request was tried multiple times
    }
}

How do I test my mock http client including the additional configuration from Program.cs like the baseaddress and retry policies?

CodePudding user response:

You cannot test the retry policy if it's setup like that, in a simple unit test. You have 2 choices.

  1. To create full-service integration tests and then get creative with mock services, following this guideline for integration tests from Microsoft: https://learn.microsoft.com/en-us/aspnet/core/test/integration-tests?view=aspnetcore-7.0#inject-mock-services.

2.To use the retry policy directly in your method which you are testing. Something like:

public async Task<string> GetStuffFromApi()
{
    var policy = MyClientPolicies.GetRetryAsyncPolicy()
    await policy.ExecuteAsync(async ctx =>

        var request = new HttpRequestMessage(HttpMethod.Get, new Uri("https://www.example.com"));
        var response = await _client.SendAsync(request);
        response.EnsureSuccessStatusCode();

        return response;
    });
}
  • Related