集成测试中的C#环境变量

时间:2019-05-28 11:34:17

标签: c# .net-core environment-variables integration-testing

我已经构建了一个自定义Web应用程序Factory,以运行用于集成测试的内存测试服务器。我们正在尝试使用sql数据库,而不是在内存数据库中使用。

我的问题是每个环境的连接字符串都在变化。我们有几个带有连接字符串的appsettings {envName} .json文件。因此,我需要找到一种获取env变量的解决方案。这些是我的尝试:

public class CustomWebApplicationSQLServerFactory<TStartup> : WebApplicationFactory<TStartup> where TStartup : class
{
    protected override void ConfigureWebHost(IWebHostBuilder builder)
    {
        builder.ConfigureServices(services =>
        {
            var serviceProvider = new ServiceCollection()
                .AddEntityFrameworkSqlServer()
                .BuildServiceProvider();

            var env = serviceProvider.GetService<IHostingEnvironment>();

            Configuration = new ConfigurationBuilder()
                .SetBasePath(AppContext.BaseDirectory)
                .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
                .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
                .AddEnvironmentVariables()
                .Build();

            var defaultConnection = Configuration.GetConnectionString("DefaultConnection");
            var connectionString = string.Format(defaultConnection, "TestSampleOrder_" + Guid.NewGuid().ToString());

            services.AddDbContext<SampleOrderContext>(options =>
            {
                options.UseSqlServer(connectionString);
                options.UseInternalServiceProvider(serviceProvider);
            });

            var sp = services.BuildServiceProvider();

            using (var scope = sp.CreateScope())
            {
                var scopedServices = scope.ServiceProvider;

                var context = scopedServices.GetRequiredService<SampleOrderContext>();

                DbInitializer.InitializeDbForTests(context);
            }
        });
    }

我还在测试项目中添加了launchSettings.json文件。在该文件中,以测试项目的名称添加了“ ASPNETCORE_ENVIRONMENT”:“ AnyValue”。因此,我不明白为什么 env = null 。完成更多测试后,env.EnvironmentName =“ Development”,应用程序名称和路径是主要项目。为什么?孔解决方案中未设置“开发”字。

我也尝试过用env代替这一行:

var env = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");

如果设置Windows变量,则可以使用该变量获取值,但我需要了解如何在launchSettings文件中设置变量的值。

我尝试过的另一件事是

var serviceProvider = services.BuildServiceProvider();

但是我真的不明白区别。

任何人都可以帮助我了解它的工作原理,获取env变量的最佳方法是什么,以及使用services.BuildServiceProvider()和new ServiceCollection()的区别是什么?

非常感谢。

1 个答案:

答案 0 :(得分:0)

也许this question可以提供一些见识。

话虽这么说,使用配置进行测试的“最简单”方法是抽象您所需的内容。也许您可以构建一个为您提供环境名称的适配器,例如:

public interface IApplicationConfiguration
{
    string GetEnvironmentName();
}

public class ApplicationConfiguration
{
    private IHostingEnvironment _hostingConfiguration;

    public ApplicationConfiguration(IHostingEnvironment hostingConfiguration)
    {
        _hostingConfiguration = hostingConfiguration;
    }

    public string GetEnvironmentName()
    {
        return _hostingConfiguration.EnvironmentName;
    }
}

可以使用其他选项解决它,但是模拟这些类型的设置可能会非常有用。