2012-02-12 19 views
21

が、私はそうのように私の自動テストで城ウィンザーを使用しようとしていますユニットテストで既存のコンポーネントの登録を無効にウィンザーコンテナは、各成分の 城ウィンザー3では、

  • Test機能アクセス方法IWindsorContainer.Resolve<T>介しコンポーネント、およびデフォルトの実装を登録する
  • 行動試験します例えば、私はIMediaPlayerProxyFactoryコンポーネントを間接的に作成するコンポーネントにアクセスする15のテストを行っているかもしれません。 SetUp関数は、十分に実装されたIMediaPlayerProxyFactoryを登録しているので、15個のテストのそれぞれでこれを登録するメンテナンスの負担はありません。

    しかし、Test_MediaPlayerProxyFactoryThrowsExceptionというテストを書いており、私のシステムがIMediaPlayerProxyFactoryコンポーネントのエラーをエレガントに処理していることを確認しています。試験方法では、私は私の特別なモック実装を作成しました、そして今私は、フレームワークに注入したい:

    this.WindsorContainer.Register(
               Component.For<IMediaPlayerProxyFactory>() 
                  .Instance(mockMediaPlayerProxyFactory) 
              ); 
    

    しかしウィンザーはメッセージ「という名前のコンポーネントが既に存在して、Castle.MicroKernel.ComponentRegistrationExceptionをスローします。 "

    すでにmockMediaPlayerProxyFactoryIMediaPlayerProxyFactoryのデフォルトインスタンスにすることはできますか?既に登録されているコンポーネントは破棄されますか?


    documentationによれば、城ウィンザー3は、登録のオーバーライドを可能にするが、私は一例を見つけることができる:

    Container.Register(
        Classes.FromThisAssembly() 
         .BasedOn<IEmptyService>() 
         .WithService.Base() 
         .ConfigureFor<EmptyServiceA>(c => c.IsDefault())); 
    

    ConfigureForBasedOnDescriptorクラスのメソッドです。私の場合は、FromDescriptorまたはBasedOnDescriptorを使用していません。

  • 答えて

    55

    あなたがオーバーライドインスタンスを作成するためにしなければならない二つのものがあります。

    1. それに固有の名前を割り当て
    2. だから仕事に例を取得するためにIsDefault方法

    を呼び出し:

    this.WindsorContainer.Register(
              Component.For<IMediaPlayerProxyFactory>() 
                 .Instance(mockMediaPlayerProxyFactory) 
                 .IsDefault() 
                 .Named("OverridingFactory") 
             ); 
    

    私はこのオーバーライドパテン多くのテストでは、私は自分の拡張メソッドを作成しました:

    public static class TestWindsorExtensions 
    { 
        public static ComponentRegistration<T> OverridesExistingRegistration<T>(this ComponentRegistration<T> componentRegistration) where T : class 
        { 
         return componentRegistration 
              .Named(Guid.NewGuid().ToString()) 
              .IsDefault(); 
        } 
    } 
    

    は今の例では、のように簡略化することができます。

    this.WindsorContainer.Register(
              Component.For<IMediaPlayerProxyFactory>() 
                 .Instance(mockMediaPlayerProxyFactory) 
                 .OverridesExistingRegistration() 
             ); 
    


    その後編集

    バージョン3.1はIsFallbackを紹介します方法。すべての初期コンポーネントをIsFallbackに登録すると、新しい登録は自動的にこれらの初期登録より優先されます。機能がその時点で利用可能だったなら、私はその道を去ったでしょう。

    https://github.com/castleproject/Windsor/blob/master/docs/whats-new-3.1.md#fallback-components

    +0

    実際の実装では、 '.IsDefault'メソッドの名前を付けて起動する必要はありません。 – bevacqua

    +1

    答えを更新していただきありがとうございます。 –

    1

    テストで容器を再使用しないでください。代わりにTearDown()nullに設定し、実際のテストごとに再初期化してください。

    +0

    申し訳ありませんが、私は明確ではありません。 'TearDown()'でコンテナを破棄し、 'SetUp()'で再初期化します。私はイントロを変えて、もっと明示しようとします。 –

    関連する問題