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

ASP.NET Core集成测试中如何自定义WebApplicationFactory设置固定RemoteIpAddress

可以直接通过扩展WebApplicationFactory的请求管道实现固定IP设置,不需要额外封装服务做Mock,实现方式如下:

方案1:直接在测试代码中inline配置

直接在创建WebApplicationFactory时注入重写IP的中间件,适合单次测试场景:

var expectedIp = IPAddress.Parse("192.168.1.123");
var factory = new WebApplicationFactory<Startup>()
    .WithWebHostBuilder(builder =>
    {
        builder.ConfigureServices(services =>
        {
            // 若原项目已注册IHttpContextAccessor可省略此行
            services.AddHttpContextAccessor();
        });
        
        builder.Configure(app =>
        {
            // 优先级最高的中间件,所有请求进来先重写远程IP
            app.Use(async (context, next) =>
            {
                context.Connection.RemoteIpAddress = expectedIp;
                await next.Invoke();
            });
            
            // 注册原有应用的中间件管道
            // 若你使用的是ASP.NET Core 6+的顶层语句启动模式,替换为你实际的启动配置
            var startup = new Startup(builder.GetSetting("Environment"));
            startup.Configure(app, builder.Services.BuildServiceProvider());
        });
    });

using var client = factory.CreateClient();
// 注意:原测试代码中GetAsync的Uri参数存在语法错误,直接传相对路径即可
var response = await client.GetAsync("/test");
var actualIp = await response.Content.ReadAsStringAsync();

// 可添加断言验证结果
// Assert.Equal(expectedIp.ToString(), actualIp);

方案2:封装自定义WebApplicationFactory复用

如果需要在多个测试用例中复用固定IP配置,可以自定义工厂类:

public class FixedIpWebApplicationFactory<TStartup> : WebApplicationFactory<TStartup> 
    where TStartup : class
{
    // 对外暴露可配置的固定IP属性
    public IPAddress RemoteIpAddress { get; set; } = IPAddress.Loopback;

    protected override void ConfigureWebHost(IWebHostBuilder builder)
    {
        builder.ConfigureServices(services =>
        {
            services.AddHttpContextAccessor();
        });

        builder.Configure(app =>
        {
            app.Use(async (context, next) =>
            {
                context.Connection.RemoteIpAddress = RemoteIpAddress;
                await next.Invoke();
            });
            
            // 加载原有应用的启动配置
            var startup = ActivatorUtilities.CreateInstance<Startup>(
                app.ApplicationServices, 
                builder.GetSetting("Environment")
            );
            startup.Configure(app, app.ApplicationServices);
        });
    }
}

测试时的调用代码:

var factory = new FixedIpWebApplicationFactory<Startup>()
{
    RemoteIpAddress = IPAddress.Parse("192.168.1.123")
};
using var client = factory.CreateClient();
// 后续请求逻辑同上

实现原理

WebApplicationFactory启动的测试服务端,所有通过CreateClient发出的请求都会经过你配置的中间件管道。我们在所有业务逻辑执行前就把Connection.RemoteIpAddress覆盖为自定义的固定值,后续控制器通过IHttpContextAccessor读取到的就是我们预设的IP,完全贴合真实运行场景,比Mock服务的方式更符合集成测试的要求。

注意:如果你的项目本身配置了ForwardedHeaders中间件处理反向代理转发的IP,需要将上述重写IP的中间件放在ForwardedHeaders中间件之后执行,避免被转发头覆盖自定义IP。

内容的提问来源于stack exchange,提问作者Józef Podlecki

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 08:36:06