0

出于教育目的,我应该如何设置 IWindsorContainer 的模拟,以便我可以对执行的注册进行单元测试?

假设我有这样的方法:

public void MakeRegistration<S, T>(IWindsorContainer container)
   where S : class
   where T : class, S
{
   container.Register(Component.For<S>().ImplementedBy<T>().LifeStyle.Transient);
}

我想为它写一个单元测试,使用起订量:

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);

正如预期的那样,上述失败了,但我很好奇如何正确测试它。

我可以使用真正的容器而不是模拟,并验证它是否解析了该类的 2 个不同实例,但我认为它不是“纯”单元测试,因为它实际上依赖于外部代码(windsor 容器本身)的工作。

正如我所说,这是理论上的,因此是否需要它超出了问题的范围。

4

1 回答 1

1

您只需要一个断言,该实现是针对纯测试Foo的服务注册的(使用NSubstitute的示例,因为我已经有一段时间没有使用 moq 了)。IFoo

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

于 2012-06-13T13:43:39.917 回答