如何在.NET 6集成测试中正确使用AddInMemoryCollection修改配置
.NET 6 最小API模式下AddInMemoryCollection配置生效方案
核心原理
.NET 5时代带Startup类的项目,主机配置逻辑拆分到Startup类中执行,而.NET 6最小API模式下配置加载逻辑在Program.cs顶层语句中提前执行,需要调整配置注入方式保证内存配置优先级高于默认配置源。
前置要求
在Web项目的.csproj文件中添加内部可见性配置,允许测试项目访问Web项目生成的internal级Program类:
<ItemGroup> <InternalsVisibleTo Include="替换为你的测试项目程序集名称" /> </ItemGroup>
正确实现方式
方案1:自定义WebApplicationFactory(推荐复用)
- 定义可注入测试配置的工厂类
public class IntegrationWebApplicationFactory<TProgram> : WebApplicationFactory<TProgram> where TProgram : class { private readonly Dictionary<string, string> _customTestConfigs = new(); public IntegrationWebApplicationFactory<TProgram> AddTestConfiguration(string key, string value) { _customTestConfigs.Add(key, value); return this; } protected override void ConfigureWebHost(IWebHostBuilder builder) { builder.ConfigureAppConfiguration((_, configBuilder) => { // 内存配置源后添加,优先级高于默认的appsettings、环境变量等配置源,会自动覆盖同名配置 configBuilder.AddInMemoryCollection(_customTestConfigs); }); base.ConfigureWebHost(builder); } }
- 测试代码调用示例
[Fact] public void ActualTest() { TryAddInMemoryCollection("http://localhost:1234"); } private void TryAddInMemoryCollection(string urlOnLocalhost) { using var factory = new IntegrationWebApplicationFactory<Program>() .AddTestConfiguration("Google", urlOnLocalhost); var testClient = factory.CreateClient(); // 后续测试逻辑 }
方案2:快速链式调用写法
无需自定义工厂,直接使用默认WebApplicationFactory配置:
private void TryAddInMemoryCollection(string urlOnLocalhost) { var testClient = new WebApplicationFactory<Program>() .WithWebHostBuilder(whb => { whb.ConfigureAppConfiguration((_, configBuilder) => { configBuilder.AddInMemoryCollection(new Dictionary<string, string> { { "Google", urlOnLocalhost } }); }); }) .CreateClient(); }
异常排查
如果配置仍未生效,可在ConfigureAppConfiguration中手动调整配置源顺序,确保内存配置优先级最高:
builder.ConfigureAppConfiguration((_, configBuilder) => { // 清空现有配置源后按需求顺序添加,内存配置放在最后保证优先级最高 configBuilder.Sources.Clear(); configBuilder.AddJsonFile("appsettings.json"); configBuilder.AddEnvironmentVariables(); configBuilder.AddInMemoryCollection(new Dictionary<string, string> { { "Google", urlOnLocalhost } }); });
内容的提问来源于stack exchange,提问作者Daan
相关产品推荐
相关产品推荐

