jplebre
jplebre

Reputation: 91

.net core asp.net unit tests that depend on files - appsettings.json - fail in travis

I've created an asp.net dot net core rtm (1.0.0-preview2-003121).

It uses ConfigurationBuilder to generate Configuration from appsettings.json:

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

    Configuration = builder.Build();
}

I've also tried '.SetBasePath(Directory.GetCurrentDirectory())`

Now my unit tests (in another project) i'm building an in-memory host: I've tried:

_server = new TestServer(new WebHostBuilder().UseStartup<Startup>());
_client = _server.CreateClient();

And I've tried:

_server = new TestServer(
        new WebHostBuilder()
            .UseContentRoot(Directory.GetCurrentDirectory())
            .UseStartup<Startup>());
_client = _server.CreateClient();

My Travis.yml file is pretty standard:

 install:
# Install .net using linux CLI commands
  - sudo sh -c 'echo "deb [arch=amd64] https://apt-mo.trafficmanager.net/repos/dotnet/ trusty main" > /etc/apt/sources.list.d/dotnetdev.list'
  - sudo apt-key adv --keyserver apt-mo.trafficmanager.net --recv-keys 417A0893
  - sudo apt-get update
  - sudo apt-get -qq install dotnet-dev-1.0.0-preview2-003121
  - sudo apt-get install dotnet-hostfxr-1.0.2

script:
  - dotnet restore
  - dotnet build src/Speakr.WebApp.Site
  - dotnet build tests/Speakr.WebApp.Site.Tests
  - dotnet test tests/Speakr.WebApp.Site.Tests -f netcoreapp1.0

Locally, all work and builds. On both Windows and Ubuntu. On travis CI tho, I'm getting the following error: Error : Speakr.WebApp.Site.Tests.InMemoryTests.HomeControllerIndexShouldNotBeNull

Has anyone seen this? I've tried adding a project.json to the test project, include CopyToOutput on the main project and include CopytoOutput on the test project.

Nada! :(

Upvotes: 6

Views: 4470

Answers (3)

Holmes Conan
Holmes Conan

Reputation: 1241

After a series of attempts, I found a possible solution. Since I need database initiation, I derived the main Startup. Several virtual functions inside the TestStartup are used to initiate the database. Then I make the Configuration inside the main Startup class protected settable. Finally:

public TestStartup(IHostingEnvironment env) : base(env)
{
    string basePath = Directory.GetCurrentDirectory();
    if (!Directory.GetCurrentDirectory().EndsWith("IntegrationTest")) {
        basePath = Path.Combine(basePath, "MyProject.IntegrationTest");
    }

    var builder = new ConfigurationBuilder();
    builder.SetBasePath(basePath)
           .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
           .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);

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

Although the basePath fetching is a little ugly, this solution works for me.

Upvotes: 1

arielorvits
arielorvits

Reputation: 5535

You should add

"buildOptions": { "copyToOutput": [ "appsettings.json" ] }

to your integration test project project.json, then .SetBasePath(env.ContentRootPath) will work, since when running the tests - appsettings.json will be at \test\IntegrationTestsProject\bin\Debug\netcoreapp1.1 - where the startup look for it.

Upvotes: 3

Kiran
Kiran

Reputation: 57989

MVC's own functional/integration tests are a good example of how you can do this.

MvcTestFixture: (Notice the 'contentRoot' is calculated) https://github.com/aspnet/Mvc/blob/1.0.0/test/Microsoft.AspNetCore.Mvc.FunctionalTests/MvcTestFixture.cs

Example of how it's used in a test: https://github.com/aspnet/Mvc/blob/1.0.0/test/Microsoft.AspNetCore.Mvc.FunctionalTests/BasicTests.cs

Website or App against which the above test verifies: https://github.com/aspnet/Mvc/tree/1.0.0/test/WebSites/BasicWebSite

Upvotes: 3

Related Questions