AppSettings.json for Integration Test in ASP.NET C

2019-01-25 05:58发布

问题:

I am following this guide. I have a Startup in the API project that uses an appsettings.json configuration file.

public class Startup
{
    public Startup(IHostingEnvironment env)
    {
        var builder = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)                
            .AddEnvironmentVariables();
        Configuration = builder.Build();

        Log.Logger = new LoggerConfiguration()
            .Enrich.FromLogContext()
            .ReadFrom.Configuration(Configuration)
            .CreateLogger();
    }

The particular part I'm looking at is the env.ContentRootPath. I did some digging around and it looks like my appsettings.json isn't actually copied to the bin folder but that is fine as ContentRootPath is returning MySolution\src\MyProject.Api\, which is where the appsettings.json file is located.

So in my integration test project I have this test:

public class TestShould
{
    private readonly TestServer _server;
    private readonly HttpClient _client;

    public TestShould()
    {
        _server = new TestServer(new WebHostBuilder().UseStartup<Startup>());
        _client = _server.CreateClient();
    }

    [Fact]
    public async Task ReturnSuccessful()
    {
        var response = await _client.GetAsync("/monitoring/test");
        response.EnsureSuccessStatusCode();

        var responseString = await response.Content.ReadAsStringAsync();

        Assert.Equal("Successful", responseString);
    }

This is basically copy and paste from the guide. When I debug this test, ContentRootPath is actually MySolution\src\MyProject.IntegrationTests\bin\Debug\net461\, which is obviously the build output folder for the test project and again the appsettings.json file is not there (yes I do have another appsettings.json file in the test project itself) so the test fails at creating the TestServer.

I tried getting around this by modifying the test project.json file.

"buildOptions": {
    "emitEntryPoint": true,
    "copyToOutput": {
        "includeFiles": [
            "appsettings.json"
       ]
    }
}

I hoped this would copy the appsettings.json file to the build output directory but it complains about the project missing a Main method for an entry point, treating the test project like a console project.

What can I do to get around this? Am I doing something wrong?

回答1:

Integration test on ASP.NET.Core 2.0 follow MS guide ,

You should right click appsettings.json set its property Copy to Output directory to Copy always

And now you could find the json file in output folder, and build TestServer with

var projectDir = System.IO.Directory.GetCurrentDirectory();
_server = new TestServer(new WebHostBuilder()
    .UseEnvironment("Development")
    .UseContentRoot(projectDir)
    .UseConfiguration(new ConfigurationBuilder()
        .SetBasePath(projectDir)
        .AddJsonFile("appsettings.json")
        .Build()
    )
    .UseStartup<TestStartup>());

Ref: TestServer w/ WebHostBuilder doesn't read appsettings.json on ASP.NET Core 2.0, but it worked on 1.1



回答2:

In the end, I followed this guide, specifically the Integration Testing section towards the bottom of the page. This removes the need to copy the appsettings.json file to the output directory. Instead it tells the test project the actual directory of the web application.

As for copying the appsettings.json to the output directory, I also managed to get that to work. Combined with the answer from dudu, I used include instead of includeFiles so the resulting section would look something like this:

"buildOptions": {
    "copyToOutput": {
        "include": "appsettings.json"
    }
}

I'm not entirely sure why this works but it does. I had a quick look at the documentation but couldn't find any real differences and since the original problem was essentially solved I didn't look further.



回答3:

Remove "emitEntryPoint": true in test project.json file.