コンポーネントを IC コンテナーに登録するコードを単体テストする必要がありますか?
もしそうなら、どのように?
コンポーネントを IC コンテナーに登録するコードを単体テストする必要がありますか?
もしそうなら、どのように?
春には、何もアサートせずにアプリケーションコンテキストをロードするだけの単体テストを行うことができます。Springは完全なコンテキストをロードするときに多くの問題について不平を言うので、これは実際には自動ビルドと組み合わせたかなり便利なテストです。
Guice IoC コンテナーを使用して行うことは、最初に、Guice を使用せずに TDD を使用していくつかの機能のクラスを生成することです (これらは単体テストです)。次に、Guice を使用してその機能の統合テストを作成します。その時点で IoC 構成 (Guice モジュール) は不完全であるため、統合テストは失敗します。TDD を使用して、統合テストに合格するまで IoC 構成を段階的に追加します。テストに合格する必要がない限り、@Inject アノテーション、構成行、またはスコープ宣言を追加しません。その結果、統合 (または受け入れ) テストを行い、IoC 構成が正しく完全であることを確認します。
これと同じ方法は、構成が非常に複雑で壊れる可能性がある IoC コンテナーまたはその他のシステムで機能するはずです。テストに合格する必要がない限り、構成を記述しないでください。
テスト プロジェクトで IoC コンテナーを実行するのは、どういうわけか間違っていると感じています。また、依存関係が解決されないことによって引き起こされるバグのほとんどは、依存関係が解決される順序によって引き起こされることにも気付きました。これを正しくテストするのは非常に難しく、単体テストとしてやりたいことではありません。
通常、クラスの初期化ルーチンで Debug.Assert ステートメントを使用します。これにより、IoC 関連のエラーに対する早期警告システムが提供され、コード内で依存関係をより適切に指定するのにも役立ちます。
@aku、@krosenvold、および @mookid は、依存関係の構成が正しいことをテストするための説得力のある引数を作成します。ただし、これは単体テスト
ではないと思います。
何をテストしていますか?コンテナ自体を単体テストしようとしているわけではありません(おそらく、それはあなたが書いた、または維持しているコードではありません)。
テストしようとしているのは、特定のタイプのすべての依存関係を作成でき、タイプを解決できることです。これは、継続的インテグレーション環境で行うと非常に便利なシステム テストまたは統合テストのように思えます。
したがって、単体テストに合格したバイナリを取得したら、コンテナーを作成し、運用環境をミラーリングするマシンでコンテナーのセットアップを実行し、コンテナーが解決できる必要がある各型が実際に作成できることをテストできます。それらの依存関係はすべてインスタンス化できます。
最新のインストーラーを適用した新しい VM でこれを実行するとよいでしょう。
一部の依存性注入フレームワーク (Unity など) には、呼び出すコンストラクターを選択するための奇妙なルールがあるため、便利な場合があります。タイプの登録と作成が正常に行われることを確認するために、単体テストを強くお勧めします。
ASP.NET MVC プロジェクトで Windsor を使用しています。ここでは、すべてのコントローラーをインスタンス化できる (つまり、依存関係を解決できる) ことを確認する簡単なテストを作成しました。
Web サイトの各構成 (「開発」、「テスト」、「someProductionSite」など) のテストがあり、その特定の構成で Windsor コンテナーを作成し、IController のすべての非抽象実装をループしてチェックします。それぞれのインスタンスを解決できること。
コントローラー ファクトリは、container.Resolve(...) になるアプリケーションへの唯一のエントリ ポイントであるため、すべての構成が有効であることを 100% 確信しています。
一般に、システム全体に関するアサーションとして機能するテストを作成することは、非常に有用で価値があることを発見しました。
たとえば、Castle の自動トランザクション管理を使用してコントローラー アクションをトランザクションで囲むため、すべてのコントローラー アクションが仮想であることも主張しています。これは要件です。
コンポーネントには独自の依存関係があるか、初期化を実行する可能性があるため、このシナリオを UT でカバーします。
何かのようなもの
iocContainer.Register(typeof(MyService1));
service = iocContainer.Get(typeof(MyService));
Debug.AssertNotNull(service);