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