単体テストを行うときは、コンテナーをまったく使用しないでください。コンストラクターを呼び出して適切なモックオブジェクトを提供することにより、テスト対象のクラスを作成するだけです。
過去にここで私を大いに助けた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());
}
統合テストでは、コンテナーを使用し、コンテナーのいくつかの依存関係を交換するのがはるかに一般的です。それでも、これらの統合テストでは、application_startで作成したコンテナーは使用されませんが、各テストは個別に実行する必要があるため、その場合、各統合テストには独自の新しいコンテナーインスタンスが含まれる可能性があります。また、application_startから単一のコンテナーを使用した場合でも、統合テストは別のプロジェクトから実行され、実行中のアプリケーションに干渉することはありません。
各統合テストは独自のコンテナーインスタンス(存在する場合)を取得する必要がありますが、それでも可能な限り多くのコンテナー構成コードを再利用する必要があります。これは、呼び出されたときに新しく構成されたコンテナーインスタンスを返すか、提供されたコンテナーインスタンスを構成する(そして何も返さない)メソッドにこのコードを抽出することで実行できます。このメソッドは通常、不完全な構成を実行する必要があり、呼び出し元(テストまたはグローバルasax)が欠落している構成を追加する必要があります。
このコードの抽出:同じ構成を部分的に共有する複数のエンドアプリケーションを持つことができます。統合テストでコンテナを検証できます。統合テストでモックする必要のあるサービスを追加できます。
生活を楽にするために、Simple Injectorを使用すると、既存の登録を新しい登録(たとえば、モックされた登録)に置き換えることができます。これは次のように有効にできます。
container.Options.AllowOverridingRegistrations = true;
しかし、これには注意してください!このオプションは、誤って登録を上書きしたという事実を隠すことができます。私の経験では、ほとんどの場合、不完全なコンテナーを作成し、不足している登録をオーバーライドするのではなく、後で追加する方がはるかに優れています。または、オーバーライドする場合は、偶発的な設定ミスを防ぐために、可能な限り最後に機能を有効にしてください。