ASP.NET Core UseSetting来自集成测试

我有一个集成测试项目,在测试类中使用.UseSetting() ,如下所示:

 public AccessTokenRetrieval() : base(nameof(AccessTokenRetrieval)) { var connectionString = GetConnectionString(); var dbSettings = new DbSettings(connectionString); _userGroupRepository = new UserGroupRepository(dbSettings); _roleRepository = new RoleRepository(dbSettings); _userRepository = new UserRepository(dbSettings); _server = new TestServer(new WebHostBuilder() .UseStartup() .UseEnvironment("IntegrationTest") .UseSetting("IntegrationTestConnString", dbSettings.IdentityServerConnectionString)); _handler = _server.CreateHandler(); _client = _server.CreateClient(); } 

我现在想在我的实际项目的Startup.cs中检索该设置。 我试图这样做:

 public void ConfigureIntegrationTestServices(IServiceCollection services) { var connectionString = Configuration.GetValue("IntegrationTestConnString"); BuildIdentityServerTests(services, connectionString); AddCoreServices(services, connectionString); } 

但这似乎返回null。

检索此设置的正确方法是什么?

每次测试设置

要将设置传递到特定的TestHost实例,您可以使用ConfigureServices调用并覆盖默认设置注册。

首先,在Startup.ConfigureServices方法中注册默认的DbSettings实例。 必须使用TryAll调用:

 public class Startup { public void ConfigureServices(IServiceCollection services) { services.TryAddSingleton(new DbSettings(...)); } } 

WebHostBuilder.ConfigureServices调用中注册一个WebHostBuilder.ConfigureServices实例:

 _server = new TestServer(new WebHostBuilder() .UseStartup() .ConfigureServices(services => { services.AddSingleton(new DbSettings(...)); } ); 

当您尝试在应用程序代码中解析DbSettings时,您将获得一个DbSettings的实例。 因为WebHostBuilder.ConfigureServices执行WebHostBuilder.ConfigureServices并且WebHostBuilder.ConfigureServices调用阻止注册默认实例。

此提示允许替换您注册的任何DI依赖项。

全局设置

要设置不变量(包含所有测试)设置,请设置进程范围的环境变量而不是UseSetting调用:

 Environment.SetEnvironmentVariable("foo", "bar"); var _server = new TestServer(new WebHostBuilder() .UseStartup() ); 

然后阅读:

 public void ConfigureServices(IServiceCollection services) { string setting1 = Configuration["foo"]; string setting2 = Environment.GetEnvironmentVariable("foo"); } 

您需要添加环境变量提供程序以从Configuration读取变量:

 public Startup(IHostingEnvironment env) { var builder = new ConfigurationBuilder() .SetBasePath(env.ContentRootPath) .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) //this config provider is mandatory to read env vars from Configuration .AddEnvironmentVariables(); Configuration = builder.Build(); } 

你可以只注入IConfigurationRoot,你可以在测试项目中使用本地配置文件。 您将丢失默认的特定于环境的配置覆盖,这是新项目模板中的默认设置,但我个人不会将它们用于配置管理(更喜欢非承诺的appsetting.local.json,这对开发人员来说是唯一的)和CI服务器)。

 var configuration = new ConfigurationBuilder() .SetBasePath(AppContext.BaseDirectory) .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) .AddJsonFile("appsettings.local.json", optional: true, reloadOnChange: true) .AddInMemoryCollection(new Dictionary { {"myConfig:setting1", "value1"}, {"myConfig:setting2", "value2"} }) .Build(); var server = new TestServer(new WebHostBuilder() .UseUrls("http://localhost:5001") .UseContentRoot(Directory.GetCurrentDirectory()) .UseStartup() .ConfigureServices(services => services.AddSingleton(configuration))); 

对于初创公司:

 public class Startup { public Startup(IConfigurationRoot configuration) { this.Configuration = configuration; } ... } 

编辑:虽然这确实有效,但它似乎也会破坏IOptionsSnapshot配置注入,从而在运行时识别配置文件更改。 我将留下这个答案,但也会继续挖掘更好的方法而不注入自定义服务只是为了支持测试/特定于夹具的配置覆盖。