1

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?

1
  • Do you want to perform unit or integration testing? Commented Jan 27, 2023 at 10:31

1 Answer 1

1

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;
    });
}
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for the link for integration testing. Are you familiar with how to do somethin similar to that for console apps? This is actually just a console app and I'm having trouble finding a WebApplicationFactory type class for console apps
Ah that complicates things a lot. The "simplest" solution I can think of is to run full integration tests without mocking anything. I found a good starting point article here itsnotbugitsfeature.com/2021/04/30/…. But then you'd have to intercept the http calls your console app is making and fake the responses. This can be achieved by using some proxy server. I can't think of an easier solution without also tampering with your production code.
How much of an undertaking does it sound like from your experience to replicate something like the WebApplicationFactory for my console app? For context we have a few dozen small console apps with a custom ConsoleAppHost and ConsoleAppHostBuilder class. Would it be worth it to do that to make integration testing easier for these kinds of apps or would you see that being a huge mess?
To replicate it fully with all features would be an extremely big effort, but to fake some services like IHttpClientFactory could be doable. Still, it's probably much cleaner and easier to create proper integration tests with some http calls interceptor. You wouldn't need to write it from scratch, there's some good starting points here. stackoverflow.com/questions/40129074/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.