C# 使用模拟(Moq)对象更改Autofac模块中的注入
我有一个Autofac模块,如下所示C# 使用模拟(Moq)对象更改Autofac模块中的注入,c#,unit-testing,moq,autofac,autofactory,C#,Unit Testing,Moq,Autofac,Autofactory,我有一个Autofac模块,如下所示 public class ServiceInjector:Module { protected override void Load(ContainerBuilder builder) { // many registrations and type looking up here ... // One of
public class ServiceInjector:Module
{
protected override void Load(ContainerBuilder builder)
{
// many registrations and type looking up here
...
// One of the registration, say t which is found
// in above looking, is a resource consuming type
builder.RegisterType(t).As<ITimeConsume>();
// ...
}
}
公共类ServiceInjector:模块
{
受保护的覆盖无效负载(ContainerBuilder builder)
{
//许多注册和类型在这里查找
...
//其中一个注册,比如说找到的t
//在上面看来,是一种资源消耗类型
builder.RegisterType(t.As();
// ...
}
}
此模块用于ServiceClass中:
public class ServiceClass
{
static IContainer _ioc;
public ServiceClass()
{
var builder = new ContainerBuilder();
builder.RegisterModule<ServiceInjector>();
_ioc = builder.Build();
}
public void InvokeService()
{
using(var scope = _ioc.BeginLifetimeScope())
{
ITimeConsume obj = scope.Resolve<ITimeConsume>(...);
var result = obj.DoTimeConsumingJob(...);
// do something about result here ...
}
}
}
公共类服务类
{
静态IContainer_ioc;
公共服务类()
{
var builder=new ContainerBuilder();
builder.RegisterModule();
_ioc=builder.Build();
}
public void InvokeService()
{
使用(var scope=\u ioc.BeginLifetimeScope())
{
ITimeConsume obj=scope.Resolve(…);
var结果=对象DoTimeConsumingJob(…);
//在这里对结果做点什么。。。
}
}
}
我的问题是:如何通过模拟(Moq)ITimeConsume类来测试ServiceClass?下面我试着写一个测试:
public void Test()
{
Mock<ITimeConsume> moc = GetMockObj(...);
// How can I inject moc.Object into ServiceInjector module,
// so that ServiceClass can use this mock object ?
}
公共无效测试()
{
Mock moc=GetMockObj(…);
//如何将moc.Object注入ServiceInjector模块,
//这样ServiceClass就可以使用这个模拟对象了?
}
如果这样做是不可能的,那么对于模拟也可以注入的耗时类,有什么更好的设计呢
**
更新:
**
谢谢@dubs和@OldFox的提示。我认为关键是Autofac喷油器应该在外部初始化,而不是内部控制。因此,我利用Autofac.ILifetimeScope的“”构建功能,并使用生存期范围参数设计ServiceClass构造函数。使用此设计,我可以在飞行时在单元测试中注册任何服务,如下例所示:
using(var scope = Ioc.BeginLifetimeScope(
builder => builder.RegisterInstance(mockObject).As<ITimeConsume>())
使用(var scope=Ioc.BeginLifetimeScope(
builder=>builder.RegisterInstance(mockObject.As())
在当前设计中,无法注入模拟对象。
更改最少的最简单解决方案是在服务类
中添加内部
Cto'r:
internal ServiceClass(IContainer ioc)
{
_ioc = ioc;
}
然后使用attribute在测试类中启用C`tor的使用
在排列/设置/测试阶段,使用包含模拟对象的容器初始化测试中的类:
[SetUp]
public void TestInit()
{
Mock<ITimeConsume> moc = GetMockObj(...);
builder.RegisterInstance(moc).As<ITimeConsume>();
...
...
_target = new ServiceClass(builder.Build());
}
[设置]
公共无效测试()
{
Mock moc=GetMockObj(…);
builder.RegisterInstance(moc.As();
...
...
_target=newServiceClass(builder.Build());
}
我个人有多个容器实例。每个端点一个
测试项目
公共类自动加载程序
{
公共静态void Configure()
{
var builder=new ContainerBuilder();
builder.RegisterModule();
builder.RegisterModule();
Container=builder.Build();
}
公共静态IContainer容器{get;set;}
}
然后,本地测试项目autofac模块可以自由地使用特定注册覆盖服务项目模块
如果多个组件公开同一服务,Autofac将使用最后注册的组件作为该服务的默认提供程序:
测试班
公共无效测试()
{
AutofacLoader.Configure();
var x=AutofacLoader.Container.Resolve();
}
public class AutofacLoader
{
public static void Configure()
{
var builder = new ContainerBuilder();
builder.RegisterModule<ServiceProject.ServiceInjector>();
builder.RegisterModule<LocalTestProject.AutofacModule>();
Container = builder.Build();
}
public static IContainer Container { get; set; }
}
public void Test()
{
AutofacLoader.Configure();
var x = AutofacLoader.Container.Resolve<ITimeConsume>();
}