Alex Rivera | Logout

Moq.Mock<T> - how to set up a method that takes an expression

Asked 2010-05-01T23:36:21.643
32

I am Mocking my repository interface and am not sure how to set up a method that takes an expression and returns an object? I am using Moq and NUnit.

Interface:

public interface IReadOnlyRepository : IDisposable
{
    IQueryable<T> All<T>() where T : class;
    T Single<T>(Expression<Func<T, bool>> expression) where T : class;
}

Test with IQueryable is already set up, but don't know how to set up the T Single:

private Moq.Mock<IReadOnlyRepository> _mockRepos;
private AdminController _controller;
[SetUp]
public void SetUp()
{
    var allPages = new List<Page>();
    for (var i = 0; i < 10; i++)
    {
        allPages.Add(new Page { Id = i, Title = "Page Title " + i, Slug = "Page-Title-" + i, Content = "Page " + i + " on page content." });
    }
    _mockRepos = new Moq.Mock<IReadOnlyRepository>();
    _mockRepos.Setup(x => x.All<Page>()).Returns(allPages.AsQueryable());
    //Not sure what to do here???
    _mockRepos.Setup(x => x.Single<Page>()
    //----
    _controller = new AdminController(_mockRepos.Object);
}
Edit
Report

1 Answer

1

Using Moq's It.IsAny<> without a .CallBack forces you to write code that's not covered by your test. Instead, it allows any query/expression at all to pass through, rendering your mock basically useless from a unit testing perspective.

The solution: You either need to use a Callback to test the expression OR you need to constrain your mock better. Either way is messy and difficult. I've dealt with this issue for as long as I've been practicing TDD. I finally threw together a helper class to make this a lot more expressive and less messy. Here's an example of one possible end-result:

mockPeopleRepository
  .Setup(x => x.Find(ThatHas.AnExpressionFor<Person>()
    .ThatMatches(correctPerson)
    .And().ThatDoesNotMatch(deletedPerson)
    .Build()))
  .Returns(_expectedListOfPeople); 

Here's the blog article that talks about it and gives the source code: http://awkwardcoder.com/2013/04/24/constraining-mocks-with-expression-arguments/

answered 2013-04-24T21:20:13.430

Your Answer