Типизированная конфигурация в функциональном тестировании с помощью xUnit c#

#c# #asp.net-core #xunit

#c# #asp.net-core #xunit

Вопрос:

Я пишу функциональные тесты для своего API с помощью xUnit. Я настроил свой API с использованием типов. Что-то вроде этого:

 public void ConfigureServices(IServiceCollection services)
{
  services.ConfigureServices(services)
          .Configure<SqlServerData>(Configuration.GetSection(nameof(SqlServerData)))
          .Configure<SolrData>(Configuration.GetSection(nameof(SolrData)));
}
  

Проблема возникает, когда я пытаюсь настроить свой тестовый сервер Microsoft.Класс AspNetCore.TestHost таким же образом:

   Server = new TestServer(
    new WebHostBuilder()
      .ConfigureServices(services =>
      {
         //SOME STUFF
      })
      .Configure(Configuration.GetSection(nameof(SqlServerData)))
      .UseStartup<TestStartup>()
 );
  

Я получаю следующую ошибку

не удается преобразовать из Microsoft.Extensions.Configuration.IConfigurationSection в System.Action<Microsoft.AspNetCore.Builder.IApplicationBuilder>

Комментарии:

1. TestStartup должна наследоваться от Startup класса вашего SUT. Таким образом, в первую очередь, совершенно необязательно добавлять эту конфигурацию снова.

Ответ №1:

Configure метод определен в WebHostBuilderExtensions классе в Microsoft.AspNetCore.Hosting сборке, и его сигнатура выглядит следующим образом:

 public static IWebHostBuilder Configure(this IWebHostBuilder hostBuilder,
  Action<IApplicationBuilder> configureApp)
{
    ...
}
  

Это означает, что вы должны передать действие, содержащее IApplicationBuilder экземпляр реализации. Нечто подобное вы можете найти в Startup классе тестируемого вами API.

 public void Configure(IApplicationBuilder app)
{
}
  

В Configure методе также могут быть введены другие зависимости при условии, что они зарегистрированы в используемом вами контейнере DI. Configure() вызывается средой выполнения, поэтому обычно вам не нужно явно вызывать ее.

Если вам нужно получить экземпляр вашей конфигурации в Configure методе, вы можете получить его (или любую другую зарегистрированную зависимость) из IServiceProvider экземпляра, который предоставляется IApplicationBuilder объектом действия настройки, которое вы передаете методу:

 Server = new TestServer(new WebHostBuilder()
    .Configure(appBuilder =>
    {
        //get the required service from the appBuilder's ApplicationServices property
        var config = appBuilder.ApplicationServices.GetService<IConfiguration>();

        var section = config.GetSection("YourSection");
        //Use your section here.
    })
    .UseStartup<TestStartup>()
  

Однако, пожалуйста, будьте осторожны, потому что на этом этапе может быть уже слишком поздно настраивать службу. Configure() в основном используется для настройки конвейера запросов. Даже если у вас может быть законный вариант использования конфигурации в нем, вы должны убедиться, что вы не можете сделать это в ConfigureServices() методе вместо этого.

Надеюсь, это поможет!

Ответ №2:

Большое спасибо за ваш ответ:

Другое дело, что мне нужно было добавить ссылку на Nuget:

 Microsoft.Extensions.Options.ConfigurationExtensions
  

Теперь я могу сделать что-то вроде:

 Server = new TestServer(
            new WebHostBuilder()
            .ConfigureServices(services =>
            {

                services.Configure<SqlServerData>(Configuration.GetSection("SqlServerData"));
                services.Configure<SolrData>(Configuration.GetSection("SolrData"));
            })
            .UseStartup<TestStartup>()
        );
  

Спасибо