ユニットテストでDIコンテナを使用しないようにしてください。単体テストでは、1つのクラスまたはモジュールを単独でテストしようとします。その領域のDIコンテナにはほとんど使用されません。
システム内のコンポーネントがどのように統合され、連携して動作するかをテストする必要があるため、統合テストでは違いがあります。その場合、多くの場合、プロダクションDI設定を使用して、偽のサービス(MailService
など)のためにいくつかのサービスをスワップしますが、可能な限り本物に近づけます。この場合、コンテナを使用してオブジェクトグラフ全体を解決します。
単体テストでDIコンテナを使用したいという願望は、しばしば無効なパターンに由来します。たとえば、テスト中のすべての依存関係を持つテスト対象のクラスを作成しようとすると、重複した初期化コードが大量に発生し、テスト中のクラスの変更がシステム全体に波及する可能性があります。数十のユニットテストを変更します。これは明らかに保守性の問題を引き起こします。
過去に私をここで多く助けてくれた1つのパターンは、単純なテストクラス固有のファクトリメソッドの使用です。このメソッドは、テスト中のクラスの作成を集中化し、テスト中のクラスの依存関係が変更されたときに行う必要がある変更の量を最小限に抑えます。
が
private ClassUnderTest CreateValidClassUnderTest(params object[] dependencies) {
return new ClassUnderTest(
dependencies.OfType<ILogger>().SingleOrDefault() ?? new FakeLogger(),
dependencies.OfType<IMailSender>().SingleOrDefault() ?? new FakeMailer(),
dependencies.OfType<IEventPublisher>().SingleOrDefault() ?? new FakePublisher());
}
このファクトリメソッドは、任意の依存関係を受け入れるparams
配列が含まれています。これは次のようなファクトリメソッドが見ることができる方法です。コードはリストから依存関係を抽出し、特定の依存関係が見つからない場合は、新しい偽実装が挿入されます。
これはほとんどのテストで1つまたは2つの依存関係に関心があるためです。他の依存関係は、クラスが機能するために必要ですが、特定のテストでは興味がありません。したがって、ファクトリメソッドは、未使用の依存関係のノイズを除去しながら、テストの対象となる依存関係のみを提供することができます。ファクトリメソッドは、したがって、次のテストを書くことがことができます:
public void Test() {
// Arrange
var logger = new ListLogger();
var cut = CreateValidClassUnderTest(logger);
// Act
cut.DoSomething();
// Arrange
Assert.IsTrue(logger.Count > 0);
}
あなたが読み取り可能な信頼できると保守性テストの書き方を学ぶことに興味があるなら、私はロイOsheroveの本ユニットテストのアート(第二版を読むためにあなたをアドバイス)。これは私を大いに助けてくれました。
あなたはどんなパターンを探していますか。テスト初期化(コンストラクタ、xunitなど)でコンテナを作成するだけではどうですか?パターンはシンプルです - 構図。 – Artyom
ユニットテストパターンに本当に関心があるなら、[xUnit Test Patterns](https://www.amazon.co.uk/xUnit-Test-Patterns-Refactoring-Code-ebook/dp/B004X1D36K/ref)を読んでください。 = dp_kinw_strp_1)。 – Steven