I want to use the IHostingEnvironment
and ConfigurationBuilder
in my functional test project, so that depending on the environment the functional tests
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.
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'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
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 e.g. make web requests such as:
var response = await httpClient.GetAsync(url);
var responseString = await response.Content.ReadAsStringAsync();