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

You can set it up like this:

_mockRepos.Setup(x => x.Single<Page>(It.IsAny<Expression<Func<Page, bool>>>()))//.Returns etc...;

However you are coming up against one of Moq's shortcomings. You would want to put an actual expression there instead of using It.IsAny, but Moq doesn't support setting up methods that take expressions with specific expressions (it's a difficult feature to implement). The difficulty comes from having to figure out whether two expressions are equivalent.

So in your test you can pass in any Expression<Func<Page,bool>> and it will pass back whatever you have setup the mock to return. The value of the test is a little diluted.


Have the .Returns call return the result of the expression against your allPages variable.

_mockRepos.Setup(x => x.Single<Page>(It.IsAny<Expression<Func<Page, bool>>>()))
    .Returns( (Expression<Func<Page, bool>> predicate) => allPages.Where(predicate) );

I have found that It.Is<T> should be used in place of It.IsAny<T> for more accurate results.

Page expectedPage = new Page {Id = 12, Title = "Some Title"};
_mockRepos.Setup(x => x.Single<Page>(It.Is<Expression<Func<Page, bool>>>(u => u.Compile().Invoke(expectedPage))))
                       .Returns(() => expectedPage);