Добавление настроек приложения тестового проекта в интеграционные тесты ASP.NET Core - PullRequest
0 голосов
/ 10 декабря 2018

Я создаю интеграционные тесты ASP.NET Core (на основе xUnit), следуя этим документам .Я хочу запустить тестовый веб-сервер с собственным appsettings.json.Моя сокращенная структура папок:

\SampleAspNetWithEfCore
\SampleAspNetWithEfCore\SampleAspNetWithEfCore.csproj
\SampleAspNetWithEfCore\Startup.cs
\SampleAspNetWithEfCore\appsettings.json
\SampleAspNetWithEfCore\Controllers\*

\SampleAspNetWithEfCore.Tests\SampleAspNetWithEfCore.Tests.csproj
\SampleAspNetWithEfCore.Tests\IntegrationTests.cs
\SampleAspNetWithEfCore.Tests\appsettings.json

, тогда у меня есть эти утилиты:

public static class ServicesExtensions
{
    public static T AddOptions<T>(this IServiceCollection services, IConfigurationSection section)
        where T : class, new()
    {
        services.Configure<T>(section);
        services.AddSingleton(provider => provider.GetRequiredService<IOptions<T>>().Value);

        return section.Get<T>();
    }
}

и внутри Startup.cs ConfigureServices(...) Я делаю это:

services.AddOptions<SystemOptions>(Configuration.GetSection("System"));

Обратимся к разделу appsettings.json следующим образом:

"System": {
  "PingMessageSuffix": " suffix-from-actual-project"
}

Пока все хорошо: это подобрано строго типизированным способом. Мой контроллер получает экземпляр SystemOptions, которыйотражает структуру json, и контроллер правильно использует суффикс.

Проблемы заключаются в построении интеграционных тестов WebHost .Я хочу запустить Startup из моего реального проекта как есть, с его собственными настройками appsettings.json, но в качестве дополнительного слоя настроек я хочу добавить appsettings.json из моего тестового csproj ,переопределение любых настроек, если применимо.Это мои appsettings из тестового проекта:

"System": {
  "PingMessageSuffix": " suffix-from-test-appsettings"
}

Вот что я попробовал:

public class CustomWebApplicationFactory : WebApplicationFactory<Startup>
{
    protected override void ConfigureWebHost(IWebHostBuilder builder)
    {
        builder
            .UseStartup<Startup>()
            .ConfigureAppConfiguration(config => config
                .AddJsonFile("appsettings.json")
            );
    }
}

Однако это не работает.Если я достиг точки останова в моем контроллере, я вижу только настройки из базового проекта.В настоящий момент контроллер просто отображает значение конфигурации, и логически результат возврата также не соответствует ожидаемому.

Документация нигде на странице не упоминает "appsettings".

Итог : Как добавить слой appSettings из файла appsettings.json тестового проекта при запуске интеграционных тестов ASP.NET Core?

Ответы [ 2 ]

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

Решено это так:

  1. Для appsettings.json в тестовом проекте установите свойства:
    • Build Action на Content
    • Copy to Output Directory to Copy if newer
  2. Используйте пользовательский WebApplicationFactory, например, так:

    public class CustomWebApplicationFactory : WebApplicationFactory<Startup>
    {
        protected override void ConfigureWebHost(IWebHostBuilder builder)
        {
            var configuration = new ConfigurationBuilder()
                .AddJsonFile("appsettings.json")
                .Build();
    
            // Note:         ↓↓↓↓
            builder.ConfigureTestServices(services => 
                services.AddOptions<SystemOptions>(configuration.GetSection("System"))
            );
        }
    }
    

И вуаля: это работает!

Первый шаг необходим для того, чтобы ConfigurationBuilder легко нашел ваш файл json.На втором шаге тонко используется конфигурация ...TestServices (если вы используете обычный метод ConfigureServices, он будет вызван до конфигурации сервиса Автозагрузки и будет перезаписан).

Сноска : комментаторы (по вопросу) упомянули, что, возможно, было бы лучше иметь файл appsettings.ci.json в проекте SUT и управлять всем с помощью среды (которую вы устанавливаете через настройки запуска или через WebHostBuilder).Документация ссылается на несколько закрытых проблем GitHub, которые предлагают то же самое: 8712 , 9060 , 7153 .В зависимости от вашего сценария и вкуса это может быть лучшим или более идиоматическим решением.

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

Для проектов модульного тестирования и проектов интеграционного тестирования потребуются свои собственные настройки приложений.Мы вызываем наш appsettings.Test.json

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

 private readonly IConfiguration _configuration;

    public HomeControllerTests()
    {
          _configuration = new ConfigurationBuilder()
           .AddJsonFile("appsettings.Test.json")
           .Build();
    }

, а затем ссылку на значение в этом файле:

_configuration["user:emailAddress"]

, где файл выглядит так:

"user": { "emailAddress": "myemail.com", …...

Для того, что вы пытаетесь сделать, вам, вероятно, потребуется создать файл appsettings.test.json, похожий на мой, который находится рядом с вашим основным файлом apsettings.Затем вы захотите протестировать среду и затем добавить файл подходящих приложений.

...