Reputation: 717
In my unit tests I want to be able to moq the "find" function of my repository in my Unit of Work that takes in a lambda express. For example:
public virtual IQueryable<T> Find(Expression<Func<T, bool>> predicate)
{
// Find OPS
}
I created test lists to represent my dbSets in my unit tests (Also I left out a lot of abstraction to make this more simple for this question):
[TestMethod]
public void FindTest()
{
var mockUnitOfWork = new Mock<IUnitOfWork>();
var testList = new List<ListObject>
{
// Test values
}
// Here is where I am stuck:
mockUnitOfWork.Setup(uow => uow.Find(It.IsAny<Expression<Func<ListObject, bool>>>()))
.Returns(/* ???? testList.Where(??????) ???? */);
}
I want to be able to use the lambda passed by the method calling the mock's find to search within my mocked list. Is this possible?
EDIT: Thanks to Chris for the answer. This is setup code to pass the lambda expression that is passed by the method that references the mock's function:
mockUnitOfWork
.Setup(uow => uow.Find(It.IsAny<Expression<Func<ListObject, bool>>>()))
.Returns(new Func<Expression<Func<ListObject, bool>>, IQueryable<ListObject>>(
expr => testList.Where(expr.Compile()).AsQueryable()));
Upvotes: 15
Views: 10694
Reputation: 6683
Yes, it is possible. You can pass a function to Returns
that takes the expression passed to Find
, compiles the expression into a Func<ListObject, bool>
, and applies that to your testList
:
mockUnitOfWork
.Setup(uow => uow.Find(It.IsAny<Expression<Func<ListObject, bool>>>()))
.Returns(new Func<Expression<Func<ListObject, bool>>, IQueryable<ListObject>>(
expr => testList.Where(expr.Compile()).AsQueryable()));
Upvotes: 30