6
votes

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! :(

3
On a side note: Technically this isn't a unit test but an integration test :P - Tseng
Yes, however, these tests are more useful to me as the controller->service->client layer is really really simple and with nothing to test, but these tests allow you to test the pipeline. So I've been "tending" to call them "my" unit tests but you are absolutely correct :) - jplebre

3 Answers

3
votes

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

3
votes

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.

1
votes

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.