Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/262.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 集成测试中的ASP.NET核心使用设置_C#_Asp.net_Testing_Asp.net Core_Integration Testing - Fatal编程技术网

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
实例。