如何测试包含BaseAddress与重试策略的Mock HttpClient?
解决方案
要测试带有BaseAddress、请求头和重试策略配置的MyClient,核心是把生产环境的配置逻辑复用或复刻到测试中,同时将MockHttpMessageHandler集成到配置好的HttpClient调用链里。以下是具体实现步骤:
步骤1:抽离配置逻辑(可选但推荐)
先把Program.cs里的HttpClient配置抽成独立的扩展方法,让测试和生产代码共用同一份配置,避免出现配置不一致的问题:
public static class HttpClientConfigExtensions { public static IHttpClientBuilder ConfigureMyClient(this IHttpClientBuilder builder) { return builder.ConfigureHttpClient(client => { client.BaseAddress = new Uri("https://somewebsite.com/api"); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/plain")); }).AddPolicyHandler(MyClientPolicies.GetRetryAsyncPolicy()); } }
修改Program.cs中的配置代码,改为调用这个扩展方法:
services.AddHttpClient<IMyClient, MyClient>().ConfigureMyClient();
步骤2:在测试中构建带完整配置的Mock HttpClient
测试时,我们需要把MockHttpMessageHandler作为底层请求处理器,再在外层包装重试策略、应用BaseAddress和请求头配置:
测试重试策略
public class MyClientTests { [Fact] public async Task MyClient_RetriesRequest_OnTransientErrors() { // Arrange var mockHttp = new MockHttpMessageHandler(); // 匹配BaseAddress拼接后的完整请求路径(假设GetStuffFromApi方法调用的是"/stuff"接口) mockHttp.When("https://somewebsite.com/api/stuff") .Respond(HttpStatusCode.RequestTimeout); // 用服务容器模拟真实注入流程,自动应用所有配置 var services = new ServiceCollection(); services.AddHttpClient<MyClient>() .ConfigureMyClient() // 将底层处理器替换为MockHttp .ConfigurePrimaryHttpMessageHandler(() => mockHttp); var serviceProvider = services.BuildServiceProvider(); var myClient = serviceProvider.GetRequiredService<MyClient>(); // Act // 预期会因多次超时抛出异常 await Assert.ThrowsAsync<HttpRequestException>(() => myClient.GetStuffFromApi()); // Assert // 假设重试策略配置为重试2次,总请求数应为3次(1次初始请求 + 2次重试) Assert.Equal(3, mockHttp.GetMatchCount("https://somewebsite.com/api/stuff")); } }
测试BaseAddress和请求头配置
[Fact] public async Task MyClient_UsesCorrectBaseAddressAndHeaders() { // Arrange var mockHttp = new MockHttpMessageHandler(); HttpRequestMessage capturedRequest = null; mockHttp.When("*") .Respond(req => { capturedRequest = req; return new HttpResponseMessage(HttpStatusCode.OK); }); // 复用配置逻辑构建客户端 var services = new ServiceCollection(); services.AddHttpClient<MyClient>() .ConfigureMyClient() .ConfigurePrimaryHttpMessageHandler(() => mockHttp); var serviceProvider = services.BuildServiceProvider(); var myClient = serviceProvider.GetRequiredService<MyClient>(); // Act await myClient.GetStuffFromApi(); // Assert // 验证BaseAddress是否正确拼接成完整请求地址 Assert.Equal(new Uri("https://somewebsite.com/api/stuff"), capturedRequest.RequestUri); // 验证默认请求头是否被正确添加 Assert.True(capturedRequest.Headers.Accept.Any(h => h.MediaType == "text/plain")); }
关键说明
- 贴近真实注入场景:通过
ServiceCollection构建测试用服务容器,能自动复用生产环境的所有配置(BaseAddress、请求头、重试策略),无需手动重复编写配置代码。 - 重试策略验证:利用
mockHttp.GetMatchCount()统计请求触发次数,直接验证重试策略是否按预期执行。 - 配置正确性验证:通过捕获请求对象,检查
RequestUri和请求头,确保BaseAddress和默认请求头被正确应用。
内容的提问来源于stack exchange,提问作者Efie
相关产品推荐
相关产品推荐

