Я использую AspNetCore 2.2
Следующие (более) документы здесь:
https://docs.microsoft.com/en-us/aspnet/core/test/integration-tests?view=aspnetcore-2.2
Я использую Autofac, мой класс запуска имеет следующие методы:
public void ConfigureServices(IServiceCollection services)
public void ConfigureContainer(ContainerBuilder containerBuilder) //this is where things can be registered directly with autofac and runs after ConfigureServices
public void Configure(...) //the method called by runtime
То, как я использую Autofac, как рекомендовано в его документах, это Program.cs like this
public class Program
{
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseKestrel()
.ConfigureServices(services => services.AddAutofac())
.UseIISIntegration()
.UseStartup<Startup>()
.ConfigureAppConfiguration((builderContext, config) =>
{
var env = builderContext.HostingEnvironment;
config
.AddJsonFile("appsettings.json", false, true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", true, true)
.AddEnvironmentVariables();
});
}
Сейчас я использую TestServer для моего тестового проекта, в котором я хочу использовать настоящий класс запуска. Но я бы хотел изменить одну из зависимостей.
Я видел, что существует метод, доступный от WebHostBuilder
до .ConfigureTestServices(services => {});
поэтому я попробовал следующее:
public abstract class ComponentTestFeature
: Feature
{
protected HttpClient HttpClient { get; }
protected ComponentTestFeature()
{
var configuration =
new ConfigurationBuilder()
.AddJsonFile("appsettings.Test.json")
.Build();
var webHostBuilder =
new WebHostBuilder()
.ConfigureServices(services => services.AddAutofac())
.ConfigureTestServices(services =>
{
services.AddScoped<IEventStoreManager, MockEventStoreManager>();
})
.UseConfiguration(configuration)
.UseStartup<Startup>();
var server = new TestServer(webHostBuilder);
HttpClient = server.CreateClient();
var myService = server.Host.Services.GetRequiredService<IEventStoreManager>();
}
}
Как видите, я хочу использовать MockEventStoreManager
реализацию для IEventStoreManager
, чтобы эта реализация была разрешена контейнером. Однако это работает не так, как ожидалось, и в MyService решена оригинальная, а не фиктивная реализация.
Кто-нибудь знает, как я могу добиться того, чего хочу?
ОБНОВЛЕНИЕ 1:
После дополнительных исследований мне пришлось создать проблему на github AspNetCore, потому что метод расширения выполняется до ConfigureContainer, поэтому я не могу переопределить зависимости autofac и не получить контейнер autofac позже.
https://github.com/aspnet/AspNetCore/issues/6522
ОБНОВЛЕНИЕ 2:
Просто к сведению, вот так выглядит Startup.cs. Как видите, все зависимости, кроме mvc, зарегистрированы в контейнере autofac.
public void ConfigureServices(IServiceCollection services)
{
services
.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}
// This is where things can be registered directly with autofac and runs after ConfigureServices, so it will override it
public void ConfigureContainer(ContainerBuilder builder)
{
builder.RegisterType<EventStoreManager>().As<IEventStoreManager>();
}
и я хочу использовать MockEventStoreManager
реализацию для IEventStoreManager
в моих тестах, поэтому мне нужно переопределить (из моего тестового проекта), что регистрация Autofac хорошим способом.