web-dev-qa-db-ja.com

IQueryable <T>をモックする方法

IQueryableを公開するリポジトリを作成しています。私のユニットテストのためにこれをモックアウトする最良の方法は何ですか?

残りのモックオブジェクトにRhinoMocksを使用しているので、次のことを試みました。

IQueryable<MyObject> QueryObject = 
    MockRepository.GenerateStub<IQueryable<MyObject>>();

これは機能しませんが、私はこれを試してみました:

IQueryable<MyObject> QueryObject = 
    (new List<MyObject> { new MyObject() }).AsQueryable();

これを行うためのより良い方法はありますか、または他のモックフレームワークでIQueryableのサポートが構築されていますか?

私のリポジトリインターフェースは次のようになります。

public interface IRepository<T> where T : TableServiceEntity
{
    IQueryable<T> Table { get; }
    void Attach(T existingItem);
    void Delete(T itemToDelete);
    void Insert(T newItem);
    T Load(string partitionKey, string rowKey);
    IEnumerable<T> Load(string partitionKey);
    IEnumerable<T> Query(IQueryable<T> query);
    IEnumerable<T> Last(int count);
    T Last();
    void Update(T item);
}

これが私がテストしたい方法です:

public Post LoadPost(int year, int month, int day, string slug)
{
    var query = from p in _blogRepository.Table
                where 
                    p.PartitionKey == Key.Partition(year, month, day) 
                    && p.Slug == slug
                select p;

    var posts = _blogRepository.Query(query.Take(1));

    return posts.First();
}

次に、LoadPostをテストするテストがあります。

[Fact]
public void LoadWillRetrieveByPartitionKeyAndRowKeyWhenUsingUriFormat()
{
    Repository
        .Stub(x => x.Query(Arg<IQueryable<Post>>.Is.Anything))
        .Return(new List<Post> {_post});

    var result = Service.LoadPost(
                            _post.Year(),
                            _post.Month(), 
                            _post.Day(), 
                            _post.Slug);

    Assert.NotNull(result);
}

コードは私の AzureBlog プロジェクトから取得されます。

36
Aaron Weiker

私は通常、あなたがテストでやったことを正確に行います。テストを作成するときは、.Netライブラリクラスが正しく機能し、バグが含まれていないことを前提としているため、テストで使用できます。テストリスト、コレクション、クエリ可能、辞書などが必要な場合は、本物を作成してテストデータを入力するだけです。これにより、テストがはるかに読みやすく、記述が速くなり、正直なところ、リスクは存在しません。

11
Grzenio

リポジトリをモックアウトしたい場合は、IQueryableをモックアウトすることはありません。代わりに、リポジトリのメソッドをモックアウトして、単体テストの実行に使用できる固定の既知の値(2番目の例など)を返します。

4
PatrickSteele

これは古い質問ですが、2セントを追加したいだけです。

SharpLiteで生成されたリポジトリで同じ問題が発生しました。これは、時々使用するASP .NET MVCフレームワーク)です。しばらくして、解決策を見つけました。唯一の問題はそれはRhinoMocksではなくMoqを使用していますが、おそらくそれを適応させる方法を見つけることができます。私はそれを行う方法について ブログ投稿はこちら を作成しました。

基本的には、IQueryableを実装するリストを作成し、それを偽のデータバックグラウンドとして使用します。私が助けることができることを願っています!

2
David Conde

これがあなたに役立つかどうかはわかりません…しかし、私はあなたが話しているようなことをしました。私のシナリオでは、リポジトリを使用するデータコンテキストクラスがありました。

まず、IQueryableメソッドを含むインターフェイス(IRepository)を作成しました。次に、このインターフェイスを実装する2つのクラスを作成しました。 1つのクラスはデータ操作にORMを使用し(DbEntityRepository)、別のクラスはクラスプロパティを使用します(MemoryRepository)。データコンテキストクラスには、IRepositoryを必要とするコンストラクターがありました。これを行うと、データコンテキストをテストするときにMemoryRepositoryを使用でき、アプリケーションにDbEntityRepositoryを使用できます。

興味があれば…codeplexでコードを見つけることができます: IQToolkitContrib

0
Tom Brothers