C# 集成测试中的ASP.NET核心使用设置
我有一个集成测试项目,它在测试类中使用C# 集成测试中的ASP.NET核心使用设置,c#,asp.net,testing,asp.net-core,integration-testing,C#,Asp.net,Testing,Asp.net Core,Integration Testing,我有一个集成测试项目,它在测试类中使用.UseSetting(),如下所示: public AccessTokenRetrieval() : base(nameof(AccessTokenRetrieval)) { var connectionString = GetConnectionString(); var dbSettings = new DbSettings(connectionString); _userGroupRepository = new UserGr
.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<Startup>()
.UseEnvironment("IntegrationTest")
.UseSetting("IntegrationTestConnString", dbSettings.IdentityServerConnectionString));
_handler = _server.CreateHandler();
_client = _server.CreateClient();
}
public AccessTokenRetrieval():base(nameof(AccessTokenRetrieval))
{
var connectionString=GetConnectionString();
var dbSettings=新的dbSettings(connectionString);
_userGroupRepository=新的userGroupRepository(dbSettings);
_角色还原=新角色还原(dbSettings);
_userRepository=新的userRepository(dbSettings);
_服务器=新的TestServer(新的WebHostBuilder()
.UseStartup()
.UseEnvironment(“集成测试”)
.UseSetting(“IntegrationTestConnString”,dbSettings.IdentityServerConnectionString));
_handler=_server.CreateHandler();
_client=_server.CreateClient();
}
现在,我想在实际项目的Startup.cs中检索该设置。我尝试使用以下方法执行此操作:
public void ConfigureIntegrationTestServices(IServiceCollection services)
{
var connectionString = Configuration.GetValue<string>("IntegrationTestConnString");
BuildIdentityServerTests(services, connectionString);
AddCoreServices(services, connectionString);
}
public void配置集成测试服务(IServiceCollection服务)
{
var connectionString=Configuration.GetValue(“IntegrationTestConnString”);
BuildIdentityServerTests(服务、连接字符串);
AddCoreServices(服务、连接字符串);
}
但这似乎返回空值
检索此设置的正确方法是什么?每个测试设置
要将设置传递到特定的TestHost
实例,可以使用ConfigureServices
调用并覆盖默认设置注册
首先,在Startup.ConfigureServices
方法中注册默认的DbSettings
实例。必须使用TryAll
呼叫:
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.TryAddSingleton(new DbSettings(...));
}
}
_server = new TestServer(new WebHostBuilder()
.UseStartup<Startup>()
.ConfigureServices(services =>
{
services.AddSingleton(new DbSettings(...));
}
);
Environment.SetEnvironmentVariable("foo", "bar");
var _server = new TestServer(new WebHostBuilder()
.UseStartup<Startup>()
);
在WebHostBuilder中注册模拟实例。ConfigureServices
调用:
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.TryAddSingleton(new DbSettings(...));
}
}
_server = new TestServer(new WebHostBuilder()
.UseStartup<Startup>()
.ConfigureServices(services =>
{
services.AddSingleton(new DbSettings(...));
}
);
Environment.SetEnvironmentVariable("foo", "bar");
var _server = new TestServer(new WebHostBuilder()
.UseStartup<Startup>()
);
然后读它:
public void ConfigureServices(IServiceCollection services)
{
string setting1 = Configuration["foo"];
string setting2 = Environment.GetEnvironmentVariable("foo");
}
您需要添加环境变量提供程序以从配置中读取变量
:
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”,可选:false,reloadOnChange:true)
.AddJsonFile(“appsettings.local.json”,可选:true,reloadOnChange:true)
.AddInMemoryCollection(新词典)
{
{“myConfig:setting1”、“value1”},
{“myConfig:setting2”,“value2”}
})
.Build();
var server=newtestserver(newwebhostbuilder()
.useURL(“http://localhost:5001")
.UseContentRoot(目录.GetCurrentDirectory())
.UseStartup()
.ConfigureServices(services=>services.AddSingleton(配置));
对于启动:
公共类启动
{
公共启动(IConfigurationRoot配置)
{
配置=配置;
}
...
}
编辑:
虽然这确实有效,但它似乎也打破了
IOptionsSnapshot
配置注入在运行时识别配置文件更改的功能。我将留下这个答案,但也将继续挖掘更好的方法,而不只是为了支持特定于测试/夹具的配置覆盖而注入自定义服务。在这样的测试中使用环境变量将产生副作用,因为测试是并行运行的。多个TestServer实例将开始交叉设置。@agartee是的,它是全局的,这就是需要env变量的原因。每个测试设置也是可能的,我把它添加到了答案中。谢谢。作为另一种选择,看看这个:很好的建议!一天前,我在Startup.ConfigureServices
方法中遇到了条件逻辑问题,并以类似的方式解决了这个问题:可以添加构造函数Startup(Dictionary)
并手动创建Startup
实例。