如何模拟windsor容器以测试注册

时间:2012-06-13 13:15:46

标签: c# nunit castle-windsor moq

出于教育目的,我应该如何设置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容器本身)。

正如我所说,这是理论上的,所以如果需要与否,则超出了问题的范围。

1 个答案:

答案 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我觉得在编写集成测试时有更多的价值,它表明连接正确,而不是确保在依赖项上调用某些方法。