web-dev-qa-db-ja.com

ユニットテストにIoCを使用する

IoCコンテナーを単体テストに使用するにはどうすればよいですか? IoCを使用して巨大なソリューション(50以上のプロジェクト)でモックを管理すると便利ですか?何か経験はありますか?単体テストでの使用に適したC#ライブラリはありますか?

97
crauscher

一般的に、単体テストはすべての責任を分離することであるため、単体テストにはDIコンテナは必要ありません。

コンストラクターインジェクションを使用するクラスを考えます

public MyClass(IMyDependency dep) { }

アプリケーション全体では、IMyDependencyの後ろに巨大な依存関係グラフが隠れている場合がありますが、単体テストでは、すべてを単一の Test Double にフラット化します。

MoqやRhinoMocksなどの動的モックを使用してTest Doubleを生成できますが、必須ではありません。

var dep = new Mock<IMyDependency>().Object;
var sut = new MyClass(dep);

場合によっては、 auto-mocking container があれば便利ですが、実稼働アプリケーションが使用するのと同じDIコンテナを使用する必要はありません。

124
Mark Seemann

Iocコンテナーを単体テストに使用するにはどうすればよいですか?

IoCは、単体テスト(モックの使用)を簡単にするプログラミングパラダイムを実施します:インターフェイスの使用、new()、シングルトンなし...

しかし、テストにIoCコンテナーを使用することは実際には要件ではなく、いくつかの機能を提供するだけです。モックの注入が、手動で行うことができます。

IoCを使用して巨大なソリューション(50以上のプロジェクト)でモックを管理すると便利ですか?

IoCを使用してモックを管理することの意味がわかりません。とにかく、テストに関しては、IoCコンテナーは通常、モックを注入するだけではありません。そして、リファクタリングを可能にする適切なIDEサポートがある場合、それを使用しないのはなぜですか?

経験はありますか?

はい、巨大なソリューションでは、これまで以上にエラーが発生せず、リファクタリングに悪影響を与えるソリューションが必要です(つまり、タイプセーフなIoCコンテナーまたは適切なIDEサポート)を介して)。

18
Pascal Thivent

私はよくテストでIoCコンテナーを使用します。確かに、それらは純粋な意味での「単体テスト」ではありません。 IMOよりBDDであり、リファクタリングを促進します。リファクタリングする自信を与えるためにテストがあります。記述が不十分なテストは、コードにセメントを注ぐようなものです。

以下を考慮してください。

[TestFixture]
public class ImageGalleryFixture : ContainerWiredFixture
{
    [Test]
    public void Should_save_image()
    {
        container.ConfigureMockFor<IFileRepository>()
            .Setup(r => r.Create(It.IsAny<IFile>()))
            .Verifiable();

        AddToGallery(new RequestWithRealFile());

        container.VerifyMockFor<IFileRepository>();
    }

    private void AddToGallery(AddBusinessImage request)
    {
        container.Resolve<BusinessPublisher>().Consume(request);
    }
}

ギャラリーに画像を追加すると、いくつかのことが起こります。画像のサイズが変更され、サムネイルが生成され、ファイルがAmazonS3に保存されます。コンテナを使用することで、テストしたい動作だけをより簡単に分離できます。この場合、これは永続的な部分です。

この手法を使用する場合、自動モッキングコンテナー拡張機能が役立ちます。 http://www.agileatwork.com/auto-mocking-unity-container-extension/

17
Mike Valenty

SimpleInjectorDryIoc (その鉱山)のような未登録/未知のサービスを解決する機能を持つコンテナを使用すると、まだ実装されていないインターフェイスのモックを返すことができます。

つまり、最初の単純な実装とそのモック化された依存関係で開発を開始し、進行するにつれてそれらを実際のものに置き換えることができます。

2
dadhi