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.
- 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;
});
}