TestStartup contained in a TestProject that inherits from API.Startup (contained in separate project) causes 404 error

怎甘沉沦 提交于 2019-12-11 17:41:55

问题


I am trying to use a StartupTest.cs with XUnit and TestServer.

I have followed these instructions using Visual Studio 2017 15.9.3:

1) Create a new solution.

2) Add an ASP.Net Core web application (web API) to the project. Call it API. No Https or Docker.

3) Add a xUnit Test project (.NET Core) to the solution. Call it: XUnitTestProject1

4) Add a reference to the Web API project from the XUnit project.

5) Install the following Nuget packages in the XUnit project: Microsoft.AspNetCore.TestHost, Microsoft.Extensions.PlatformAbstractions and Microsoft.AspNetCore.All.

6) Add the following class to the Unit Test project (note that Startup is the Startup.cs from the web api project):

using API;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.TestHost;
using Microsoft.Extensions.PlatformAbstractions;
using System;
using System.IO;
using System.Net.Http;


namespace XUnitTestProject1
{
    public class TestServerFixture : IDisposable
    {
        private readonly TestServer _testServer;
        public HttpClient Client { get; }

        public TestServerFixture()
        {
            var builder = new WebHostBuilder()
                   .UseContentRoot(GetContentRootPath())
                   .UseEnvironment("Test")
                   .UseStartup<Startup>();  // Uses Start up class from your API Host project to configure the test server

            _testServer = new TestServer(builder);
            Client = _testServer.CreateClient();

        }

         private string GetContentRootPath()
    {
        var testProjectPath = PlatformServices.Default.Application.ApplicationBasePath;
        var relativePathToHostProject = @"..\..\..\..\..\..\TestHost";
        return Path.Combine(testProjectPath, relativePathToHostProject);
    }

        public void Dispose()
        {
            Client.Dispose();
            _testServer.Dispose();
        }
    }
}

8) Add this test to the test project:

using System;
using Xunit;

namespace XUnitTestProject1
{
    public class UnitTest1
    {
        private readonly TestServerFixture _fixture;

        public UnitTest1(TestServerFixture fixture)
        {
            _fixture = new TestServerFixture(); //Make sure class implements IClassFixture.
        }

        [Fact]
        public async System.Threading.Tasks.Task Test1Async()
        {
            var response = await _fixture.Client.GetAsync("api/Values");

            response.EnsureSuccessStatusCode();

            var responseStrong = await response.Content.ReadAsStringAsync();
        }
    }
}

9) Run the test and receive a successful response (200). All is well up to this point.

10) The next step is to create a TestStartup class in the Unit Test project:

public class StartupTest : Startup
    { 
        public StartupTest(IConfiguration env) : base(env)
        {
        }     
    }

Note: I realise this Startup class is pointless at the moment - I do plan to override some methods once I get it working.

11) Amend the code in point 6 i.e. change this line:

.UseStartup<Startup>(); 

to:

.UseStartup<StartupTest>(); 

12) Run the test again and see a 404 response instead of 200 response.

Why do I see a 404 response after I add the TestStartup class.

TestStartup inherits from API.Startup.


回答1:


I found the answer here: https://github.com/aspnet/Mvc/issues/5992. I simply had to override ConfigureServices in StartupTest as follows:

public override void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1).AddApplicationPart(typeof(ValuesController).Assembly);
        }



回答2:


In your:

var builder = new WebHostBuilder()
               ...
               .ConfigureServices(InitializeServices)
               ....;

And add this method to your TestServerFixture.cs

protected virtual void InitializeServices(IServiceCollection services)
    {
        var startupAssembly = typeof(TestStartup).GetTypeInfo().Assembly;

        var manager = new ApplicationPartManager();
        manager.ApplicationParts.Add(new AssemblyPart(startupAssembly));
        manager.ApplicationParts.Add(new AssemblyPart(typeof(ValuesController).Assembly));
        manager.FeatureProviders.Add(new ControllerFeatureProvider());
        manager.FeatureProviders.Add(new ViewComponentFeatureProvider());
        services.AddSingleton(manager);
    }


来源:https://stackoverflow.com/questions/53681935/teststartup-contained-in-a-testproject-that-inherits-from-api-startup-contained

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!