简体   繁体   中英

Using ASP.NET Core's ConfigurationBuilder in a Test Project

I want to use the IHostingEnvironment and ConfigurationBuilder in my functional test project, so that depending on the environment the functional tests run using a different set of configuration. I want to make use of the code below:

public IConfigurationRoot ConfigureConfiguration(IHostingEnvironment hostingEnvironment)
{
    var builder = new ConfigurationBuilder()
        .AddJsonFile("appsettings.json")
        .AddJsonFile($"appsettings.{hostingEnvironment.EnvironmentName}.json", true)
        .AddEnvironmentVariables();
    return builder.Build();
}

I want to have an appSettings.json and appSettings.Production.json file to point my functional tests at production. Is this possible? How can it be achieved? I would need an instance of IHostingEnvironment .

You can use the ConfigurationBuilder in a test project with a couple of steps. I don't think you will need the IHostingEnvironment interface itself.

First, add two NuGet packages to your project which have the ConfigurationBuilder extension methods:

"dependencies": {
  "Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0-rc1-final",
  "Microsoft.Extensions.Configuration.Json": "1.0.0-rc1-final"
}

Second, put your desired environment variables into the test project's properties:

环境变量对话框

Then you can create your own builder in the test project:

private readonly IConfigurationRoot _configuration;

public BuildConfig()
{
    var environmentName = Environment.GetEnvironmentVariable("Hosting:Environment");

    var config = new ConfigurationBuilder()
        .AddJsonFile("appsettings.json")
        .AddJsonFile($"appsettings.{environmentName}.json", true)
        .AddEnvironmentVariables();

    _configuration = config.Build();
}

If you want to use precisely the same settings file (not a copy), then you'll need to add in a path to it.

I'll add this answer here for completeness, as I experienced the same issue as @vaindil describes in Will's answer here . The reason was that we populated our IConfiguration from environment variables in the code under test. This overrode any config we set in test using say an appsettings.json. Our solution was to create environment variables for the test process using System.Environment.SetEnvironvironmentVariable("variableName", "variableValue")

Effectively, the instance of WebHostBuilder in our tests is created the same as our hosted API:

// Code omitted for brevity
var builder = new WebHostBuilder()                 
                .UseEnvironment("Development")
                .ConfigureAppConfiguration(configurationBuilder => configurationBuilder.AddEnvironmentVariables())
                .UseStartup<Startup>();

var testServer = new TestServer(builder); // test against this

This is possible, according to the ASP.NET Core documentation ( http://docs.asp.net/en/latest/fundamentals/configuration.html ) you can build this inside the Startup method and add the Environment variable appSettings. When specifing the optional flag you can use the appSettings.Production.json for production environment and appSettings.json for development when there is no appSettings.Development.json available. The appsettings.{env.EnvironmentName}.json is only used when the file is present and the fallback is the default appsettings.json

public Startup(IHostingEnvironment env)
{
    // Set up configuration providers.
    var builder = new ConfigurationBuilder()
        .AddJsonFile("appsettings.json")
        .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);

    if (env.IsDevelopment())
    {
        // For more details on using the user secret store see http://go.microsoft.com/fwlink/?LinkID=532709
        builder.AddUserSecrets();
    }

    builder.AddEnvironmentVariables();
    Configuration = builder.Build();
}

I added an appsettings.Development.json to the root of my test project. Then I added the appsettings file via the .ConfigureAppConfiguration() method. It will then call the main application's Startup() method but use the configuration settings in appsettings.Development.json .


    string Environment = "Development";

    var server = new TestServer(new WebHostBuilder()                
        .UseEnvironment(Environment)
        .ConfigureAppConfiguration(x => {
            x.SetBasePath(Directory.GetCurrentDirectory());
            x.AddJsonFile($"appsettings.{Environment}.json", optional: false, reloadOnChange: true);
            x.AddEnvironmentVariables();
            })
        .UseStartup<Startup>()                
        );

    httpClient = server.CreateClient();

The httpClient can then be used to eg make web requests such as:

var response = await httpClient.GetAsync(url);
var responseString = await response.Content.ReadAsStringAsync();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM