web-dev-qa-db-ja.com

MoqとUnityを使用してユニットテストのリポジトリオブジェクトをモックする適切な方法

私の仕事では、モックにUnityを使用し、IOCコンテナーにUnityを使用しています。私はこれにかなり慣れていないので、ベストプラクティスを決定するのに役立つリソースがあまりありません。使用する。

現在、私は特定のプロセスがその仕事をするために使用する必要があるリポジトリインターフェイスのグループ(例:IRepository1、IRepository2 ... IRepository4)を持っています。

実際のコードでは、IOCコンテナーを使用し、RegisterType()メソッドを使用することで、すべてのIRepositoryオブジェクトを判別できます。

上記の4つのリポジトリを必要とするメソッドをテストするための最良の方法を見つけようとしています。

Unity IOCコンテナーの新しいインスタンスを登録し、各インスタンスのMock.Object値で渡される各モックオブジェクトのコンテナーでRegisterInstanceを呼び出すだけでよいと考えていました。この登録プロセスは再利用可能であるため、ユニットテストでリポジトリから特定のデータを取得する必要がない限り、各ユニットテストで何度も同じことを繰り返す必要はありません。ここに問題があります...何が最良かモックされたリポジトリに期待値を設定する方法?UnityコンテナーでRegisterTypeを呼び出すだけでは、実際のMockオブジェクトへの参照が失われ、動作をオーバーライドできないようです。

35
Rob Packwood

単体テストではコンテナをまったく使用しないでください。依存性注入(DI)には2つのフェーズがあります。

  1. DIパターンを使用して、依存関係をコンシューマーに注入します。そのためにコンテナは必要ありません。
  2. アプリケーションの Composition Root で、DIコンテナー(または貧者のDI)を使用してすべてのコンポーネントを一緒に配線します。

単体テストでDIコンテナをまったく使用しない方法

例として、IRepository1を使用するクラスを考えます。 Constructor Injectionパターンを使用して、依存関係をクラスの不変条件にすることができます。

public class SomeClass
{
    private readonly IRepository1 repository;

    public SomeClass(IRepository1 repository)
    {
        if (repository == null)
        {
            throw new ArgumentNullException("repository");
        }

        this.repository = repository;
    }

    // More members...
}

readonlyキーワードとGuard句を組み合わせると、インスタンスが正常にインスタンス化された場合にrepositoryフィールドがnullにならないことが保証されます。

MyClassの新しいインスタンスを作成するためにコンテナーは必要ありません。 Moqまたは別のTest Doubleを使用して単体テストから直接実行できます。

[TestMethod]
public void Test6()
{
    var repStub = new Mock<IRepository1>();
    var sut = new SomeClass(repStub.Object);
    // The rest of the test...
}

詳細については こちら を参照してください...

Unit Testingをユニットテストに使用する方法

ただし、テストで絶対にUnityを使用する必要がある場合は、コンテナーを作成してRegisterInstanceメソッドを使用できます。

[TestMethod]
public void Test7()
{
    var repMock = new Mock<IRepository1>();

    var container = new UnityContainer();
    container.RegisterInstance<IRepository1>(repMock.Object);

    var sut = container.Resolve<SomeClass>();
    // The rest of the test...
}
62
Mark Seemann