ユニットテストでのIoCの使用


97

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


7
@Mark Seemannは控えめすぎて指摘できませんが、この質問に興味がある場合は、少なくともAutoFixtureを
Ruben Bartelink

1
Miguel CastroによるVimeoのDIとモッキングの関係についての良い話があります:vimeo.com/68390510
GregC

回答:


131

一般的に言って、ユニットテストはすべての責任を分離するためのものなので、DIテストはユニットテストに必要ではありません。

コンストラクターインジェクションを使用するクラスを検討する

public MyClass(IMyDependency dep) { }

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

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

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

場合によっては、自動モックコンテナーを使用すると便利なことがありますが、本番アプリケーションで使用するのと同じDIコンテナーを使用する必要はありません。


13
合意された...テストの対象は、IoCコンテナを持っていない限りとして、依存関係、あなたのテストは、あなたがあなたのユニットテストを行うときにオブジェクトグラフの大部分を除去しようとしている...それらを必要はありません。
アンダーソンイメス09/09/23

4
@Mark Seemannこれは理にかなっています...しかし、統合テストはどうですか?つまり、UIテストをいじって、コンポジションルートを共有しなければならない状況に直面しました。コメントは?
Arnis Lapsa、2010

5
@Arnis L .:統合テストではそれほど重要ではありません。DIコンテナーを使用してコンポーネントを配線することを選択できますが、そうである場合、皮下テストまたは完全なシステムテストを実行する場合を除いて、完全なアプリケーションとは異なるコンテナーの構成が必要になる可能性があります。コンテナのアプリケーションの設定を再利用できます。
Mark Seemann、2010

msdn Magazine Test Doubleへの参照: download.microsoft.com/download/3/A/7/…–
M.Hassan

18

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

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

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

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

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

何か経験はありますか?

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


17

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

以下を検討してください。

[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/


8
「コードをセメントに注ぐような」というフレーズの+1。ずっと使い始めています。
アンドリューシェパード

2

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

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.