Как получить конфигурацию из WebApplicationFactory?

#c# #integration-testing

#c# #интеграция-тестирование

Вопрос:

В настоящее время я пишу интеграционный тест для тестирования своих API с использованием WebApplicationFactory.

Я создал CustomWebApplicationFactory. Я хочу прочитать файл appsettings.json по умолчанию, который находится в основном веб-проекте. Я знаю, что это может быть достигнуто, как показано ниже:

 private static readonly IConfigurationRoot _configuration; // Global

// Inside Constructor
var builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", true, true)

 _configuration = builder.Build();

// To get connectionstring

var connStr = _configuration.GetConnectionString("DefaultConnection");
  

В моем случае я хочу использовать appsettings.json по умолчанию. Есть ли способ получить строку подключения, прочитав appsettings.json из
основного веб-проекта без определения кодов AddJsonFile в конструкторе?

Ответ №1:

Вы можете сделать это таким образом (код ниже). Т.е. перехватить конструктор и создать конфигурацию так же, как это делает служба.

 public class MyApiServiceWrapper : WebApplicationFactory<Api.Startup>
{
    private IConfiguration _configuration;

    protected override void ConfigureWebHost(IWebHostBuilder builder)
    {
        builder.ConfigureAppConfiguration((context, conf) =>
        {
            // expand default config with settings designed for Integration Tests
            conf.AddJsonFile(Path.Combine(Directory.GetCurrentDirectory(), "appsettings.Integration.json"));
            conf.AddEnvironmentVariables();

            // here we can "compile" the settings. Api.Setup will do the same, it doesn't matter.
            _configuration = conf.Build();
        });

        builder.ConfigureTestServices(srv =>
        {
            // here you can change some internal services of the Api.Startup
            // and change them to mocks
        });

        base.ConfigureWebHost(builder);
    }

    public TConfig GetConfiguration<TConfig>()
    {
        // start my service to get the config built...
        this.CreateClient(); 
        // ... and then cast it to my type
        return _configuratio.Get<TConfig>();
    }
}
  

Ответ №2:

Для следующей настройки:

 public class Fixtures
{
    public readonly WebApplicationFactory<WebApplication1.Program> Factory { get; }
    
    public Fixtures()
    {
        Factory = new WebApplicationFactory<Startup>().WithWebHostBuilder(builder =>
        {
            builder.ConfigureServices(services =>
            {
                services.Configure<YourSettings>(settings =>
                {
                    settings.Setting1 = "OverrideSetting1"
                });
            });
        });
    }
}
  

Если вы используете шаблон Options, вы можете попробовать запросить свои настройки у IServiceProvider с помощью метода GetService<T>:

 public class Test
{
    private readonly YourSettings _settings;
    
    public Test(Fixtures fixtures)
    {
        var settingsOptions = fixtures.Factory.Services.GetService<IOptions<YourSettings>>();
        _settings = settingsOptions?.Value;
    }
}