Moq Expression with Constraint ... It.Is<Expression<Func<T, bool>>>

It seems that the real problem here is how to compare two lambda expressions, as you try to do in the It.Is<Expression<Func<UserBinding, bool>>> (criteria => criteria == testExpression) clause. Using @neleus's answer to this question, I could came up with this test that actually passes:

readonly Mock<IBindingManager> bindingManager = new Mock<IBindingManager>();

[Test]
public void TestMethod()
{
    Expression<Func<string, bool>> testExpression = binding => (binding == "Testing Framework");

    bindingManager.Setup(c => c.GetUserBinding(It.Is<Expression<Func<string, bool>>>(
        criteria => LambdaCompare.Eq(criteria, testExpression)))).Returns(new List<string>());

    var oc = new OtherClass(bindingManager.Object);

    var actual = oc.Test(b => b == "Testing Framework");

    Assert.That(actual, Is.Not.Null);
    bindingManager.Verify(c => c.GetUserBinding(It.Is<Expression<Func<string, bool>>>(
        criteria => LambdaCompare.Eq(criteria, testExpression))), Times.Once());
}

Please note the use of the LambdaCompare.Eq static method to compare that the expressions are the same. If I compare the expressions just with == or even Equals, the test fails.


When I was looking for the way to to mock Where() and filter some data, in code under tests looks like:

Repository<Customer>().Where(x=>x.IsActive).ToList() 

I could design such example based on answers form others:

 var inputTestDataAsNonFilteredCustomers = new List<Customer> {cust1, cust2};
 var customersRepoMock = new Mock<IBaseRepository<Customer>>();

                IQueryable<Customer> filteredResult = null;
                customersRepoMock.Setup(x => x.Where(It.IsAny<Expression<Func<Customer, bool>>>()))
                    .Callback((Expression<Func<Customer, bool>>[] expressions) =>
                    {
                        if (expressions == null || expressions.Any() == false)
                        {
                            return;
                        }
                        Func<Customer, bool> wereLambdaExpression = expressions.First().Compile();  //  x=>x.isActive is here
                        filteredResult = inputTestDataAsNonFilteredCustomers.Where(wereLambdaExpression).ToList().AsQueryable();// x=>x.isActive was applied
                    })
                   .Returns(() => filteredResult.AsQueryable());

Maybe it will be helpful for feather developers.

Tags:

C#

Moq