placing asp.net 5 tests in separate assembly

2019-05-14 06:31发布

问题:

I use Microsoft.AspNet.TestHost to host xunit integration tests. As Long as the tests are in the very same Project as the asp.net-5-solution everything works as it should.
But I'd like to place the tests into a separate assembly, to separate them from the solution. But when I try to run the tests in the separate solution I get an error, TestServer can't find the views.

Bsoft.Buchhaltung.Tests.LoginTests.SomeTest [FAIL]
  System.InvalidOperationException : The view 'About' was not found. The following locations were searched:
  /Views/Home/About.cshtml
  /Views/Shared/About.cshtml.

I guess the TestServer is looking relative to the local Directory for the views. How can I get it to look in the correct project path instead?

回答1:

Matt Ridgway's answer was written, when RC1 was the current version. Now (RTM 1.0.0 / 1.0.1) this has gotten simpler:

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

    public TenantTests()
    {
        _server = new TestServer(new WebHostBuilder()
                .UseContentRoot(Path.GetFullPath(Path.Combine(PlatformServices.Default.Application.ApplicationBasePath, "..", "..", "..", "..", "..", "SaaSDemo.Web")))
                .UseEnvironment("Development")
                .UseStartup<Startup>());
        _client = _server.CreateClient();

    }

    [Fact]
    public async Task DefaultPageExists()
    {
        var response = await _client.GetAsync("/");

        response.EnsureSuccessStatusCode();

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

        Assert.True(!string.IsNullOrEmpty(responseString));

    }
}

The key point here is .UseContentRoot(Path.GetFullPath(Path.Combine(PlatformServices.Default.Application.ApplicationBasePath, "..", "..", "..", "..", "..", "SaaSDemo.Web")))

The ApplicationBasePath is in your test assemblies bin/debug/{platform-version}/{os-buildarchitecture}/ folder. You need to traverse that tree upwards, until you reach your project containing your views. In my case. SaasDemo.Tests is in the same folder as SaasDemo.Web, so traversing up 5 folders was the right amount.



回答2:

I've got a sample repo here - https://github.com/mattridgway/ASPNET5-MVC6-Integration-Tests that shows the fix (thanks to David Fowler).

TL;DR - When setting up the TestServer you need to set the application base path to look at the other project so it can find the views.



回答3:

For future reference, note that you can now set the content root like this:

string contentRoot = "path/to/your/web/project";
IWebHostBuilder hostBuilder = new WebHostBuilder()
    .UseContentRoot(contentRoot)
    .UseStartup<Startup>();
_server = new TestServer(hostBuilder);
_client = _server.CreateClient();


回答4:

One more additional change that I had to do to get an overridden startup class to work is to set the ApplicationName in the IHostingEnvironment object to the actual name of the web project (Name of the web assembly).

public TestStartup(IHostingEnvironment env) : base(env)
        {
            env.ApplicationName = "Demo.Web";
        }

This is required when the TestStartup is in a different assembly and overrides the original Startup class. UseContentRoot was still required in my case.

If the name is not set, I always got a 404 not found.