开发者

How do I mock IQueryable<T>

I am creating a repository that exposes IQueryable. What is the best way to mock this out for my unit testing?

Since I am using RhinoMocks for the rest of my mock objects, I tried to do the following:

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

This doesn't work though so I tried doing this:

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

Is there a better way to do this, or have any other mocking frameworks built support for IQueryable in?

My repository interface looks like this:

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);
}

Here is the method that I want to test:

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();
}

Then here is the test as I have it right now that will test 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);
}

The code is taken from my AzureBlog project.


I usually do exactly what you ended up doing in your test. When writing my tests I assume that the .Net library classes work correctly and don't contain bugs, so I can use them in the tests. When I need a test list, collection, queryable, dictionary, etc. I just create the real thing and populate with test data. It makes the tests much more readable and quicker to write, and to be honest the risk is non-existent.


If you want to mock out your repository, you won't be mocking IQueryable. Instead, mock out the methods of your repository to return fixed, known values (like your second example) that can be used to run your unit tests.


I know this is an old question, but just want to add my 2 cents.

I had the same issue with the repositories generated with SharpLite, which is a ASP .NET MVC framework I use from time to time. After some time, I found out a solution, the only issue is that is using Moq, and not Rhino Mocks, but possibly you can find a way to adapt it. I made a blog post here on how to do it.

It's basically creating a list that implements IQueryable and using it as a fake data background. Hope I can help!


I’m not sure if this will help you… but I did something like what you are talking about. In my scenario, I had a data context class that used the repository.

I started off by creating an interface (IRepository) that included the IQueryable method. Then I created two classes that implement this interface. One class uses an ORM for data manipulation (DbEntityRepository) and another class uses a class property (MemoryRepository). The data context class had a constructor that required the IRepository. Doing this I could use the MemoryRepository for when Testing the data context and I could use the DbEntityRepository for the Application.

If you are interested… you can find the code on codeplex: IQToolkitContrib

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜