При использовании компоновщика веб-хоста с WebHostBuilder.ConfigureServices
службы, настроенные на компоновщике, регистрируются в очень конкретное время, когда создается веб-хост. Однако ConfigureServices
в вашем классе Startup
называется после этого .
Таким образом, хотя вы можете использовать ConfigureServices
на компоновщике для добавления сервисов на ваш веб-хостинг, Startup
по-прежнему позволяет перезаписывать все. Обычно это хорошая вещь, но, конечно, она не поможет вам, когда вы захотите провести интеграционное тестирование своего приложения.
Я бы предложил вам использовать новый WebApplicationFactory
для создания интеграционных тестов. Он уже поставляется с множеством утилит, которые помогут вам с вашими интеграционными тестами .
Одна из вещей, которую фабрика позволяет вам делать, - вводить фиктивные службы для тестирования . Для этого вы можете использовать ConfigureTestServices
метод расширения в конструкторе веб-хоста.
Под капотами фабрика веб-приложений использует IStartupConfigureServicesFilter
для этой работы. Вы можете зарегистрировать реализации этого в своем приложении, и их метод ConfigureServices
будет запущен для настройки конвейера конфигурации службы для типа Startup
. Таким образом, вы можете зарегистрировать несколько действий по настройке и запускать их явно в конце.
Так что если по какой-то причине вы не можете или не хотите использовать фабрику веб-приложений (хотя это значительно упрощает интеграционное тестирование), вы все равно можете сделать это в явном виде следующим образом:
var webHostBuilder = WebHost.CreateDefaultBuilder()
.UseStartup<Startup>()
.ConfigureServices(services =>
{
services.AddSingleton<IStartupConfigureServicesFilter>(new MockInjectorFilter(s =>
{
s.AddScoped(p => topicWriterFake);
});
});
public class MockInjectorFilter : IStartupConfigureServicesFilter
{
private readonly Action<IServiceCollection> _configureServices;
public ConfigureTestServicesStartupConfigureServicesFilter(Action<IServiceCollection> configureServices)
=> _configureServices = configureServices ?? throw new ArgumentNullException(nameof(configureServices));
public Action<IServiceCollection> ConfigureServices(Action<IServiceCollection> next)
=> serviceCollection =>
{
next(serviceCollection);
_configureServices(serviceCollection);
};
}