2

コンストラクターインジェクションを介してDIの代わりにIoCコンテナーを使用しています。コンストラクターインジェクションの代わりにIoCコンテナーを使用している理由を尋ねる人もいるかもしれません。ここに記載されている理由により、単純なDIコードではなくIoCコンテナーが必要なのはなぜですか?。ただし、サービスの単体テストを作成するのは難しいと感じています。コンストラクタインジェクション(難問)を使用していないため、実行時にサービスで使用されるリポジトリをモックする方法がわかりません。誰かが解決策を持っていますか?

例えば:

public class SomeService
{
    private ISomeServiceRepository someServiceRepository;

    public GetSomeThing()
    {
        //how do I mock this repository in my unit test
        someServiceRepository = IoC.Resolve<ISomeServiceRepository>();

        someData = someServiceRepository.getData();

        someOtherService = new SomeOtherService();
        someThing = someOtherService.GetSomeThing();

        return FigureOutSomeThingElse(someData, someThing);
    }

    public FigureOutSomeThingElse(someData, someThing)
    {
        //do some figuring
        return somethingElse;
    }
} 

public class SomeOtherService
{
    private ISomeServiceRepository someOtherServiceRepository;

    public GetSomeThing()
    {
        //how do I mock this repository in my unit test
        someOtherServiceRepository = IoC.Resolve<ISomeOtherServiceRepository>();

        var someData = someOtherServiceRepository.getData();
        return someData;
    }
}
4

3 に答える 3

2

人々は、必要に応じて解決して「あなたは間違っている」と簡単に批判することができますが、私はレジスター - 解決 - 解放パターンを利他的に理解できない古いコードベースの痛みを経験しました。ただし、( のようにIoC.) 静的コンテナー参照を使用しないようにアドバイスし、コンテナー自体を少なくとも注入するようにします。

この状況では、IoC 登録コンテナーのテスト バージョンを提供するだけですが、通常のアプリ構成の代わりに、テスト構成をコーディングします。

これは真の意味でのモックやスタブではなく、実際、これらの用語はソリューションをかなり混乱させる可能性があります。

本質的に、単体テストでは、アクティブな構成が異なるだけです。型を手動で登録する必要があり、単体テストの実行パスにある場合、現在の構成コードを無効にするのが難しい場合があります。

必要に応じて IoC パターン (少数の型) で解決するコンテナーがあり、テスト用に単純に新しいコンテナーを作成しました (基本的に、1 つの構成をコード用に、もう 1 つを単体テスト用に)。私たちのユースケースは、あなたのケースのように静的にアクセス可能な型を持つのではなく、コンテナをクラスに注入したという点で少し異なりました。

于 2012-07-11T13:54:43.307 に答える
0

わかった、これは私がやったことです...

(Unity.Net と RhinoMock を使用しています)

  • IContainerAccessor を実装する baseUnitTest クラスを作成しました

  • コンストラクターで UnityContainer の新しいインスタンスを作成して初期化しました

  • IContainerAccessor.Container を実装する「UnityContainer」読み取り専用パブリック プロパティを作成しました。

  • baseUnitTest を継承した単体テストクラスを作成

  • テストメソッドに次のコードを追加しました...

    モッカー = 新しい Rhino.Mocks.MockRepository()

    SomeRepository = Mocker.DynamicMock(ISomeRepository の)()

    MyBase.UnityContainer.RegisterInstance(ISomeRepository の)(SomeRepository)

    Rhino.Mocks.Expect.Call(Of SomeResult)(SomeRepository.SomeMethod("someArg")).Return(New SomeResult())

    Mocker.ReplayAll()

    someService = 新しい SomeService()

    'このメソッドは IOC.Resolve(ISomeRepository) を使用し、SomeRepository.SomeMethod を呼び出します someResult = someService.someMethod()

    Assert.IsNotNull(someResult)

  • 終わり

于 2012-07-17T14:39:58.637 に答える