TestStartup, содержащийся в TestProject, который наследуется от API.Startup (содержится в отдельном проекте) вызывает ошибку 404 - PullRequest
0 голосов
/ 08 декабря 2018

Я пытаюсь использовать StartupTest.cs с XUnit и TestServer.

Я следовал этим инструкциям, используя Visual Studio 2017 15.9.3:

1) Создайте новое решение.

2) Добавьте веб-приложение ASP.Net Core (веб)API) к проекту.Назовите это API.Нет Https или Docker.

3) Добавьте проект xUnit Test (.NET Core) в решение.Назовите его: XUnitTestProject1

4) Добавьте ссылку на проект Web API из проекта XUnit.

5) Установите следующие пакеты Nuget в проект XUnit: Microsoft.AspNetCore.TestHost, Microsoft.Extensions.PlatformAbstractions и Microsoft.AspNetCore.All.

6) Добавьте следующий класс в проект модульного теста (обратите внимание, что Startup - это Startup.cs из проекта веб-API):

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) Добавьте этот тест в тестовый проект:

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) Запустите тест и получите успешный ответ (200).Все хорошо до этого момента.

10) Следующим шагом является создание класса TestStartup в проекте модульного теста:

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

Примечание: я понимаю, что этот класс запуска не имеет смысла вмомент - я планирую переопределить некоторые методы, как только я получу его работу.

11) Изменить код в пункте 6, т.е. изменить эту строку:

.UseStartup<Startup>(); 

на:

.UseStartup<StartupTest>(); 

12) Запустите тест снова и увидите ответ 404 вместо ответа 200.

Почему я вижу ответ 404 после добавления класса TestStartup.

TestStartup наследуется отAPI.Startup.

Ответы [ 2 ]

0 голосов
/ 08 декабря 2018

В вашем:

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

И добавьте этот метод к вашему 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);
    }
0 голосов
/ 08 декабря 2018

Я нашел ответ здесь: https://github.com/aspnet/Mvc/issues/5992. Мне просто пришлось переопределить ConfigureServices в StartupTest следующим образом:

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