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

使用WebApplicationFactory测试时,app.Run带URL参数引发异常的解决

解决.NET 6中WebApplicationFactory测试因指定app.Run URL导致的异常

问题原因

测试时WebApplicationFactory默认使用TestServer,而TestServer初始化时不会自动添加IServerAddressesFeature,直接调用带URL参数的app.Run()会触发找不到该Feature的异常。


方案1:根据环境条件分支运行

在服务的Program.cs中判断运行环境,测试环境下调用无参数的app.Run(),避免指定URL:

public static void Main(string[] args)
{
    var builder = WebApplication.CreateBuilder(args);

    var startup = new Startup(builder.Configuration);
    startup.ConfigureServices(builder.Services);

    var app = builder.Build();

    startup.Configure(app);

    // 识别测试环境,分支执行
    if (builder.Environment.IsEnvironment("Test"))
    {
        app.Run();
    }
    else
    {
        app.Run("http://+:5202");
    }
}

测试代码中指定测试环境:

public ServiceController_should(WebApplicationFactory<Startup> factory)
{
    _client = factory
        .WithWebHostBuilder(builder =>
        {
            builder.UseEnvironment("Test");
            builder.ConfigureServices(services =>
            {
                // 自定义DI配置
            });
        })
        .CreateClient();
}

方案2:给TestServer手动添加IServerAddressesFeature

在测试的WebHost配置中,手动注入IServerAddressesFeature,让app.Run()能找到对应的Feature:

public ServiceController_should(WebApplicationFactory<Startup> factory)
{
    _client = factory
        .WithWebHostBuilder(builder =>
        {
            builder.ConfigureServices(services =>
            {
                // 自定义DI配置
            });
            // 给TestServer添加地址Feature
            builder.ConfigureTestServices(services =>
            {
                services.PostConfigure<TestServerOptions>(options =>
                {
                    options.Features.Set<IServerAddressesFeature>(new ServerAddressesFeature
                    {
                        Addresses = { "http://+:5202" }
                    });
                });
            });
        })
        .CreateClient();
}

方案3:通过配置文件管理URL

把URL从硬编码改为从配置读取,测试时可灵活覆盖配置:

  1. 在服务的appsettings.json中添加URL配置:
{
  "Urls": "http://+:5202"
}
  1. 修改Program.cs的Main方法:
public static void Main(string[] args)
{
    var builder = WebApplication.CreateBuilder(args);

    var startup = new Startup(builder.Configuration);
    startup.ConfigureServices(builder.Services);

    var app = builder.Build();

    startup.Configure(app);

    // 从配置读取URL,无配置则用默认
    var url = builder.Configuration["Urls"];
    if (!string.IsNullOrEmpty(url))
    {
        app.Run(url);
    }
    else
    {
        app.Run();
    }
}
  1. 测试时覆盖配置:
public ServiceController_should(WebApplicationFactory<Startup> factory)
{
    _client = factory
        .WithWebHostBuilder(builder =>
        {
            builder.ConfigureAppConfiguration(config =>
            {
                config.AddInMemoryCollection(new Dictionary<string, string>
                {
                    { "Urls", "" } // 测试时清空URL配置
                });
            });
            builder.ConfigureServices(services =>
            {
                // 自定义DI配置
            });
        })
        .CreateClient();
}

内容的提问来源于stack exchange,提问作者Puddleofpandas

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 22:05:12