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