You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何测试包含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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 00:16:13