此blog post显示了使用Castle Windsor和NSubstitute实现自动模拟的方法。
我不知道或使用Castle Windsor,但我确实使用Unity和NSubstitute。
有没有办法做他用Unity演示的东西?
以下是帖子的相关内容:
首先,将ILazyComponentLoader注册到Windsor:
var c = new WindsorContainer();
c.Register(Component.For<LazyComponentAutoMocker>());
然后,LazyComponentAutoMocker的实现就是这样:
public class LazyComponentAutoMocker : ILazyComponentLoader
{
public IRegistration Load(string key, Type service, IDictionary arguments)
{
return Component.For(service).Instance(Substitute.For(new[] { service }, null));
}
}
你已经完成了!这是一个简单的单元测试示例,仅使用上面的代码:
[Test]
public void IDictionary_Add_Invoked()
{
var dict = c.Resolve<IDictionary>();
dict.Add(1, 1);
dict.Received().Add(1, 1);
}
答案 0 :(得分:3)
使用Unity,您可以编写自定义容器扩展来执行自动锁定。
根据此article,您需要以下内容:
编辑:我的实施示例中有一个错误:请参阅此问题:NSubstitute and Unity
所以固定代码看起来像这样:
public class AutoMockingContainerExtension : UnityContainerExtension
{
protected override void Initialize()
{
var strategy = new AutoMockingBuilderStrategy(Container);
Context.Strategies.Add(strategy, UnityBuildStage.PreCreation);
}
class AutoMockingBuilderStrategy : BuilderStrategy
{
private readonly IUnityContainer container;
private readonly Dictionary<Type, object> substitutes
= new Dictionary<Type, object>();
public AutoMockingBuilderStrategy(IUnityContainer container)
{
this.container = container;
}
public override void PreBuildUp(IBuilderContext context)
{
var key = context.OriginalBuildKey;
if (key.Type.IsInterface && !container.IsRegistered(key.Type))
{
context.Existing = GetOrCreateSubstitute(key.Type);
context.BuildComplete = true;
}
}
private object GetOrCreateSubstitute(Type type)
{
if (substitutes.ContainsKey(type))
return substitutes[type];
var substitute = Substitute.For(new[] {type}, null);
substitutes.Add(type, substitute);
return substitute;
}
}
}
您可以在创建cotainer时注册它:
IUnityContainer container = new UnityContainer();
container.AddExtension(new AutoMockingContainerExtension());