出于教育目的,我应该如何设置IWindsorContainer的模拟,以便我可以对已执行的注册进行单元测试?
假设我有这样的方法:
public void MakeRegistration<S, T>(IWindsorContainer container)
where S : class
where T : class, S
{
container.Register(Component.For<S>().ImplementedBy<T>().LifeStyle.Transient);
}
我想用Moq编写一个单元测试:
var container = new Mock<IWindsorContainer>(MockBehavior.Strict);
container.Setup(c => c.Register(
Component.For<IFoo>()
.ImplementedBy<Foo>()
.LifeStyle.Transient));
var registrar = new MyRegistrar();
registrar.MakeRegistration<IFoo, Foo>(container.Object);
如上所述,上述失败,但我很好奇如何正确测试它。
我可以使用真正的容器而不是模拟,并验证它解析了类的两个不同实例,但我认为它不是“纯”单元测试,因为它实际上依赖于外部代码的工作(windsor容器本身)。
正如我所说,这是理论上的,所以如果需要与否,则超出了问题的范围。
答案 0 :(得分:1)
您只需要一个断言,即实现Foo
已针对服务IFoo
注册,这将是纯测试(使用NSubstitute的示例,因为我有一段时间没有使用moq)
[ Test ]
public void Should_register_implemenation_of_Foo_for_service_IFoo()
{
var container = Substitute.For<IWindsorContainer>();
container.Register( Component.For<IFoo>().ImplementedBy<Foo>() );
container.Received().Register( Arg.Is<IRegistration[]>(x => Test(x) ));
}
private bool Test(IRegistration[] registrations)
{
var fooRegistration = (ComponentRegistration<IFoo>) registrations[ 0 ];
return fooRegistration.Implementation == typeof(Foo);
}
public interface IFoo {}
public class Foo : IFoo {}
我知道你已经说过理论上的问题,但重要的是要问下面这个问题,以便TDD新手认为你必须这样做。
测试是否应该指示组件如何实现目标,还是只测试组件实际实现目标?
IMO我觉得在编写集成测试时有更多的价值,它表明连接正确,而不是确保在依赖项上调用某些方法。