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

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

上記は予想通り失敗しますが、適切にテストする方法に興味があります。

モックの代わりに実際のコンテナーを使用して、クラスの2つの異なるインスタンスを解決することを確認できますが、実際には外部コード(ウィンザーコンテナー自体)の動作に依存しているため、「純粋な」単体テストではないと思います。

私が言ったように、これは理論的なものなので、それが必要かどうかは問題の範囲外です。

4

1 に答える 1

1

純粋なテストとなるFooサービスに対して実装が登録されているというアサーションが必要です(私はしばらくmoqを使用していないため、 NSubstituteを使用した例)。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 に答える