C# 模拟和解决AspNetCore与TestServer集成测试中的Autofac依赖关系
我正在使用aspnetcore2.2 以下(更多)是此处的文档: 我使用的是Autofac,我的Startup类有以下方法:C# 模拟和解决AspNetCore与TestServer集成测试中的Autofac依赖关系,c#,asp.net-core,integration-testing,autofac,asp.net-core-testhost,C#,Asp.net Core,Integration Testing,Autofac,Asp.net Core Testhost,我正在使用aspnetcore2.2 以下(更多)是此处的文档: 我使用的是Autofac,我的Startup类有以下方法: public void ConfigureServices(IServiceCollection services) public void ConfigureContainer(ContainerBuilder containerBuilder) //this is where things can be registered directly with autofa
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
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();
});
}
如您所见,我想为IEventStoreManager
使用MockEventStoreManager
实现,因此这是应该由容器解决的实现。然而,这并没有像预期的那样工作,myService解决的是原始实现,真实的实现,而不是模拟的实现
有人知道我怎样才能达到我想要的吗
更新1:
经过更多的调查后,我不得不在github AspNetCore上创建一个问题,因为扩展方法在ConfigureContainer之前执行,因此我无法真正重写autofac依赖项,也无法稍后检索autofac容器。
更新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>();
}
public void配置服务(IServiceCollection服务)
{
服务
.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}
//在这里,可以直接向autofac注册并在ConfigureServices之后运行,因此它将覆盖它
公共void配置容器(ContainerBuilder生成器)
{
builder.RegisterType().As();
}
我想做的是在测试中使用
MockEventStoreManager
实现IEventStoreManager
,因此我需要以一种好的方式覆盖(从测试项目中)Autofac的注册。有两个选项:
- 在testserver中自定义依赖项的实现 计划
- 实现并手动注册一个类似于“Moq”的依赖项的模拟实现
/。。。
.ConfigureServices(服务=>services.AddAutofac())
.ConfigureTestContainer(生成器=>{
builder.RegisterType().As();
})
//...
这应该避免获得由Startup.ConfigureContainer
添加的实际实现
如果多个组件公开同一服务,Autofac将使用最后注册的组件作为该服务的默认提供程序:
参考文献
ConfigureTestContainer
在启动后被调用。ConfigureContainer
因此最后一次向mock注册将是该服务的默认提供程序。除了Nkosi的优秀功能之外,我想提一提的是,ConfigureTestContainer
在.NET Core 3.0之后不适用于通用主机。然而,有一个问题。不幸的是,它依赖于已在.NET 5.0中删除的弃用的IStartpConfigureContainerFilter
这意味着当前在.NET 5.0中,当使用通用主机时,无法在集成测试中模拟外部DI容器注入的依赖项
幸运的是,ASP.NET团队的David Fowler。流中的原始
IEventStoreManager
注册在哪里ConfigureServices
或直接使用ConfigureContainer
中的容器?在ConfigureContainer
中,使用autofac container就像ConfigureTestServices
一样,有一个ConfigureTestContainer
可用于直接操作容器。检查更新的答案。我在testserver项目中有一个接口的自定义实现。实际上,它在内部使用Moq,而不是使用与外部系统的真正连接。问题是,在测试时,我无法告诉我的应用程序要使用的具体实现是模拟的实现,而不是在Startup.cs的ConfigureContainer上注册的实现。换句话说,我无法从TestServerFor Asp.Net Core 3.0+或通用托管服务覆盖autofac的容器。AddAutofac()
不起作用。来自Autofac代码文档:“仅适用于ASP.NET 3.0之前的托管。这不适用于ASP.NET CORE 3.0+或通用托管。”
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>();
}
//...
.ConfigureServices(services => services.AddAutofac())
.ConfigureTestContainer<ContainerBuilder>(builder => {
builder.RegisterType<MockEventStoreManager>().As<IEventStoreManager>();
})
//...