Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASPNet.Core HostingEnvironment for Integration Tests?

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;
}
like image 940
MB34 Avatar asked Oct 27 '17 15:10

MB34


People also ask

Which package component can be added for integration testing of the .NET core API applications?

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.

Can Nunit be used for integration testing?

ASP.NET Core has an extremely useful integration testing framework, in the form of the NuGet package Microsoft.

What are the types of integration testing?

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.


2 Answers

ASP .Net Core 2.0

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();
}
like image 183
Steven T. Cramer Avatar answered Nov 15 '22 01:11

Steven T. Cramer


Copy the appsettings.json file to the integration tests project folder and set it to Copy Always and it works correctly.

like image 35
MB34 Avatar answered Nov 14 '22 23:11

MB34