2010-11-24 35 views
6

私はDIコンテナを使用していますが、MSTest(VS 2010)単体テストをコンテナから解決されたインスタンスで実行します。MSTest TestMethod依存性注入

これらのインスタンスを私のTestMethodまたは少なくとも私のTestClassに注入したいのですが。これは可能ですか?

今私のTestMethodsは直接私の注射テストがより現実的であるように私が避けたいと思うcontainer.Resolve<T>(xxx)を直接呼び出します。

誰でもこの経験がありますか?

ありがとうございます。

答えて

6

テストクラスのインスタンス化は、MSTestフレームワークの内部クラスで深く行われるため、依存関係を注入するのは難しい作業です。

5

依存性注入パターンに従ってコードを記述し、IoCフレームワークを使用する主な理由は、テスト可能なコードを取得することです。ただし、テストコードでIoCコンテナを使用すると、逆の結果になります。あなたの質問から私はあなたがすでにこれを体験しているのを見ることができます。

これは、依存関係注入(DI)パターンの代わりにサービス・ロケーター(SL)パターンを使用する場合に特に問題となります。 SLパターンでは、クラスはIoCコンテナ(またはそのようなコンテナの抽象化)を、必要な依存性をクラスに提供する代わりに(コンストラクタインジェクションを使用して)直接呼び出します。クラスはコンテナを直接呼び出しているため、テスト環境でもそのコンテナを設定する必要があります。テストフレームワークはあなたのテストを並行して実行するかもしれないので、テスト環境や偽のオブジェクトはしばしば非常に複雑になります。なぜなら、テストベースごとに偽の動作に影響を与えたいからです。 MSTestはこれを行います)。

あなたのアプリケーションコードにDIパターンを使用する必要があります。テストでは、あなたはあなたのテストでたとえば、HomeControllerクラスのテストをICustomerServiceクラスに依存する場合は、通常、テストクラスのHomeControllerの作成を集中化するCreateController()またはCreateValidControllerファクトリメソッドを使用する必要があります。このようなファクトリメソッドでは、クラスを手作業で以下のようにして注入します:

private static HomeController CreateController(
    InMemoryDataMapper mapper) 
{ 
    var uowFactory = new FakeNorthwindUnitOfWorkFactory() 
    { 
     UnitOfWork = new NorthwindUnitOfWork(mapper); 
    }; 

    return new HomeController(new FakeCustomerService(uowFactory)); 
} 

HomeControllerの依存関係の仕組みについては、そのようなファクトリメソッドはもちろんどのように見えますか(意図はありません)。

簡単に言えば、アプリケーションコードで実行したいのと同じ方法で、テストコードに依存性注入を行わないでください。テストフレームワークではこれを実行することが非常に難しいだけでなく、テスト環境用にIoCフレームワークを構成する必要があります。その場合は、失敗する可能性があります。残念ながら、私は経験から話します。

+0

私はSLパターンを使用していません。幸いなことにコンストラクタインジェクションだけです。私は同じ懸念を抱いていて、MSBuildがデフォルトでは並行してテストを実行しないのを見ているので、並列テストに関する正確な質問をしていると思いますが、おそらく間違っています。 – Jeff

+1

私はすべてのテストコードで依存関係の認識と有効期間の設定を複製する必要がありますか?言い換えれば、コンテナ内にシングルトンであるコンポーネントがあるとし、テストに必要な5つの一時コンポーネントのコンストラクタに注入する必要があるとします。シングルトンのインスタンスを手動でインスタンス化し、シングルトンとして保持して、手動でインスタンス化する各依存コンポーネントに注入することを知っているテストのセットアップを行う必要がありますか?コンポーネントがシングルトンにならない場合はどうなりますか?私はこのために私のテストセットアップコードをすべて書き直さなければならないのですか? – Jeff

+0

インスタンスコンストラクタに注入するコンポーネントやサービスの可用性をテストするのはどうですか?インスタンシエーションを手動で行う場合は、この重要な機能をテストすることができません。状態を維持することは、通常、プログラミングのより繊細な部分の1つであり、コンポーネントの可用性をテストしていない場合は、状態管理の有効性を完全にテストすることができません。プログラミングにおける私の最も強い信念の1つはDRYです。具体的には、「2つの場所で状態を維持しないでください! – Jeff