使用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从硬编码改为从配置读取,测试时可灵活覆盖配置:
- 在服务的
appsettings.json中添加URL配置:
{ "Urls": "http://+:5202" }
- 修改
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(); } }
- 测试时覆盖配置:
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
相关产品推荐
相关产品推荐

