In building the Integration tests for my ASPNet.Core web app, https://docs.microsoft.com/en-us/aspnet/core/testing/integration-testing,
I am coming across an issue. The Startup is run when I run the app and the configuration is read and contains all the information in my apsettings.json
file.
Now, when I run the integration test as shown below. the Startup is run but the configuration is different. Why would that happen and how do I make sure it reads
the one for the app itself?
[TestFixture]
class HSMControllerTests
{
private readonly TestServer _server;
private readonly HttpClient _client;
public HSMControllerTests()
{
_server = new TestServer(new WebHostBuilder()
.UseStartup<Startup>());
_client = _server.CreateClient();
}
[Test]
public async global::System.Threading.Tasks.Task GET_PingHSM_ShouldSucceedAsync()
{
HttpResponseMessage response = await _client.GetAsync("HSM/PingHSM");
Assert.NotNull(response);
Assert.IsInstanceOf<OkObjectResult>(response);
}
}
I am getting the exception Missing configuration section ServiceConfig.
This is how the WebHost is built in Program.cs
in my app:
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.UseKestrel(o => o.AddServerHeader = false)
.Build();
Could the difference in how it is built in the Test code be the problem?
Modified ControllerTest constructor:
public HSMControllerTests()
{
var builder = new ConfigurationBuilder()
.SetBasePath(Path.GetFullPath(@"../../../../HSM.WebApi.IntegrationTests"))
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddEnvironmentVariables();
Configuration = builder.Build();
_server = new TestServer(WebHost.CreateDefaultBuilder()
.UseStartup<Startup>());
_client = _server.CreateClient();
}
Now, how to inject the new Configuration into the Startup? Our Startup is defined like this:
public Startup(IConfiguration configuration, IHostingEnvironment environment)
: base(typeof(Startup), configuration, environment)
{
}
modification based on last post by @poke
_server = new TestServer(WebHost.CreateDefaultBuilder()
.ConfigureAppConfiguration(configBuilder => new ConfigurationBuilder()
.SetBasePath(Path.GetFullPath(@"../../../../HSM.WebApi.IntegrationTests"))
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddEnvironmentVariables()
)
.UseStartup<Startup>());
Got it working, somewhat...
var config = new ConfigurationBuilder()
.SetBasePath(Path.GetFullPath(@"../../../../HSM.WebApi.IntegrationTests"))
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddEnvironmentVariables();
var Configuration = config.Build();
_server = new TestServer(WebHost.CreateDefaultBuilder()
.UseConfiguration(Configuration)
.UseStartup<Startup>());
_client = _server.CreateClient();
But now, the HostingEnvironment is set to the directory of the Tests app vs. the directory of the Web app and it attempts to read to appsettings.json
file from there in the HomeController constructor, here:
public HSMController(IHostingEnvironment hostingEnvironment)
{
_hostingEnvironment = hostingEnvironment;
contentRootPath = _hostingEnvironment.ContentRootPath;
}
The test web host (TestServer) is available in a NuGet component as Microsoft. AspNetCore. TestHost. It can be added to integration test projects and used to host ASP.NET Core applications.
ASP.NET Core has an extremely useful integration testing framework, in the form of the NuGet package Microsoft.
Some different types of integration testing are big-bang, mixed (sandwich), risky-hardest, top-down, and bottom-up. Other Integration Patterns are: collaboration integration, backbone integration, layer integration, client-server integration, distributed services integration and high-frequency integration.
Copy you appsettings.json files to your integration test and set them to copy always.
Create MyTestServer Class as it will likely be reused in many tests. Remember that CreateDefaultBuilder will automatically load your appsettings and use environment.
public class ApiTestServer : TestServer
{
public ApiTestServer() : base(WebHostBuilder())
{ }
private static IWebHostBuilder WebHostBuilder() =>
WebHost.CreateDefaultBuilder()
.UseStartup<Startup>()
.UseEnvironment("Local")
.UseKestrel(options =>
{
options.Listen(IPAddress.Any, 5001);
});
}
Then in your test
public SettingsTests()
{
TestServer = new ApiTestServer();
HttpClient = TestServer.CreateClient();
}
Copy the appsettings.json
file to the integration tests project folder and set it to Copy Always and it works correctly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With