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()));
A lambda expression is a short block of code which takes in parameters and returns a value. Lambda expressions are similar to methods, but they do not need a name and they can be implemented right in the body of a method.
No, there isn't. Lambda expressions are optimised (in terms of syntax) for the single parameter case. I know that the C# team feels your pain, and have tried to find an alternative. Whether there ever will be one or not is a different matter.
In lambda expressions, you can't use the ref or out parameters.
You use a lambda expression to create an anonymous function. Use the lambda declaration operator => to separate the lambda's parameter list from its body. A lambda expression can be of any of the following two forms: Expression lambda that has an expression as its body: C# Copy.
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()));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With