WebApplicationFactory выдает ошибку, что contentRootPath не существует в интеграционном тесте ASP.NET Core - PullRequest
0 голосов
/ 12 ноября 2018

У меня есть проект ASP.NET Core с несколькими простыми страницами Razor и контроллером веб-API.

Я использую Чистая архитектура в качестве отправной точки. Я переименовал названия проектов, удалил материал MVC и добавил свой собственный код. Все работает и работает.

Однако интеграционные тесты выдают следующую ошибку при вызове factory.CreateClient():

Test Name:  ToDo.Tests.Integration.Web.HomeControllerIndexShould.ReturnViewWithCorrectMessage
Test FullName:  ToDo.Tests.Integration.Web.HomeControllerIndexShould.ReturnViewWithCorrectMessage
Test Source:    C:\Source\Utopia\tests\ToDo.Tests\Integration\Web\HomeControllerIndexShould.cs : line 18
Test Outcome:   Failed
Test Duration:  0:00:00,001

Result StackTrace:  
at Microsoft.AspNetCore.Hosting.Internal.HostingEnvironmentExtensions.Initialize(IHostingEnvironment hostingEnvironment, String contentRootPath, WebHostOptions options)
   at Microsoft.AspNetCore.Hosting.WebHostBuilder.BuildCommonServices(AggregateException& hostingStartupErrors)
   at Microsoft.AspNetCore.Hosting.WebHostBuilder.Build()
   at Microsoft.AspNetCore.TestHost.TestServer..ctor(IWebHostBuilder builder, IFeatureCollection featureCollection)
   at Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory`1.CreateServer(IWebHostBuilder builder)
   at Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory`1.EnsureServer()
   at Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory`1.CreateDefaultClient(DelegatingHandler[] handlers)
   at Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory`1.CreateClient(WebApplicationFactoryClientOptions options)
   at ToDo.Tests.Integration.Web.HomeControllerIndexShould..ctor(CustomWebApplicationFactory`1 factory) in C:\Source\Utopia\tests\ToDo.Tests\Integration\Web\HomeControllerIndexShould.cs:line 14
Result Message: 
System.ArgumentException : The content root 'C:\Source\Utopia\ToDo.Web' does not exist.
Parameter name: contentRootPath

Я пытался настроить пользовательский WebApplicationFactory , используя builder.UseContentRoot и builder.UseSolutionRelativeContentRoot, но он продолжает выдавать одну и ту же ошибку независимо от того, какие значения я использую для методов ContentRoot.

Я не знаю, почему мои тесты терпят неудачу, в то время как те, что в образце Чистой архитектуры работают. Я тоже не знаю, как это исправить.

Любые указатели высоко ценятся!

Ответы [ 5 ]

0 голосов
/ 13 августа 2019

Мое решение этой проблемы - определить WebApplicationFactory при запуске приложения, но настроить WebHostBuilder с TestStartup.

Пример:

public class MyApplicationFactory : WebApplicationFactory<Startup>
{
    protected override IWebHostBuilder CreateWebHostBuilder()
    {
        return WebHost.CreateDefaultBuilder();
    }

    protected override void ConfigureWebHost(IWebHostBuilder builder)
    {
        builder.UseStartup<TestStartup>();

        base.ConfigureWebHost(builder);
    }
}
0 голосов
/ 03 июня 2019

Кажется, что WebApplicationFactory должен использовать реальный класс Startup в качестве типа аргумента:

class TestWebApplicationFactory : WebApplicationFactory<Startup>
{
     protected override IWebHostBuilder CreateWebHostBuilder()
     {
         return WebHost.CreateDefaultBuilder<TestableStartup>();
     }
}

Обратите внимание, что Startup является типом истинного кода SUT, а TestableStartup является конфигурацией TestingStartup.

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

Этот метод работал для меня

        var client = _factory
            .WithWebHostBuilder(builder => builder.UseSolutionRelativeContentRoot("relative/path/of/project/under/test"))
            .CreateClient();

См. Как тестовая инфраструктура выводит корневой каталог содержимого приложения для получения дополнительной информации.

0 голосов
/ 14 января 2019

Если вы используете ReSharper, это может быть связано с версией.Мы обнаружили проблему с версией 2018.3.Добавление UseSolutionRelativeContentRoot разрешило его.

    protected override void ConfigureWebHost(IWebHostBuilder builder)
    {
            builder.UseKestrel()
            .UseSolutionRelativeContentRoot("")
            .ConfigureAppConfiguration((context, configBuilder) =>
            {
              // Config code
            })
            .UseStartup<Startup>();
    }
0 голосов
/ 13 ноября 2018

Я не совсем уверен, о чем вы говорите, но вы не должны настраивать подобные вещи в тестовом проекте, во-первых.Вместо этого вы должны создать класс, подобный TestStartup, и наследовать от класса Startup SUT.В классе Startup SUT вы должны выделить такие вещи, как настройки вашей БД и тому подобное, в виртуальные частные методы, которые затем можно переопределить на TestStartup.Например, вы можете создать метод вроде:

private virtual void ConfigureDatabase(IServiceCollection services)
{
    services.AddDbContext<MyContext>(o =>
        o.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
}

Затем в вашем TestStartup вы добавите что-то вроде:

private override void ConfigureDatabase(IServiceCollection services)
{
    var databaseName = Guid.NewGuid().ToString();
    services.AddDbContext<MyContext>(o =>
        o.UseInMemoryDatabase(databaseName));
}

Затем при настройке фабрики длятестируя, вы говорите использовать TestStartup:

var client = factory.WithWebHostBuilder(b => b.UseStartup<TestStartup>()).CreateClient();

Или вы можете создать свой собственный WebApplicationFactory и установить его там:

public class CustomWebApplicationFactory<TStartup> : WebApplicationFactory<RazorPagesProject.Startup>
{
    protected override void ConfigureWebHost(IWebHostBuilder builder)
    {
        builder.UseStartup<TestStartup>();
    }
}

Просто помнитечто параметр общего типа TStartup предназначен для получения сборки точки входа, поэтому вы все равно должны поместить туда Startup.

Суть в том, что вам не нужно повторять весь ваш запускконфигурации, а затем не забудьте сохранить синхронизацию.Ваш тестовый клиент будет использовать ту же конфигурацию запуска, которую используют ваши настоящие приложения, за исключением нескольких сохраненных замен, таких как использование базы данных в памяти.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...