Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Moq with lambda expressions?

I am trying to test an application service using Moq 4.0.10827 (on NuGet) and need to query a repository:

public class MyService
{
    Repository<MyObject> _Repo;

    public MyObject Get (string SomeConstraint)
    {
        return _Repo
            .GetTheFirstOneOrReturnNull (M => M.Constraint.Equals (
                SomeContraint, StringComparison.InvariantCultureIgnoreCase
            ));  // GetTheFirstOneOrReturnNull takes a Func<MyObject, bool>
    }
}

How do I replicate the lambda expression with Moq? I keep getting the "Unsupported expression" exception.

Here is an idea of what I'm doing already:

[TestMethod]
public void GetByMyConstraintShouldReturnWithMyObject ()
{
    // Arrange
    const string MyConstraint = "Constraint";
    MyObject Expected = new MyObject { Constraint = MyConstraint };
    Mock<Repository<MyObject>> MockRepo = new Mock<Repository<MyObject>> ();
    MockRepo.Setup (x => x.GetTheFirstOneOrReturnNull (M => M.Constraint.Equals (MyConstraint, StringComparison.InvariantCultureIgnoreCase)))
            .Returns (Expected).Verifable ();
    MyService Service = new MyService (MockRepo.Object);

    // Act
    MyObject Result = Service.Get (MyConstraint);


    // Assert
    Assert.AreSame (Expected, Result);
    MockRepo.Verify ();

}

I've looked around at some of the other answers but I cannot really make out what I am doing incorrectly (admittedly a "noob" with Moq). I have come to the conclusion that this is going to be a pain but I have a lot of tests like this coming up and want to get solid now instead of drowning later.

Is the only option to encapsulate the lambda expression inside of an object and pass in the repository and have it execute the query? I don't want to change my code just for my testing environment, but I don't want to waste time trying to bend this thing to my will, either.

like image 265
Jim D'Angelo Avatar asked Feb 12 '26 05:02

Jim D'Angelo


2 Answers

This shouldn't need much testing. One correct test will show the code delegating to FirstOrDefault is working, then all subsequent tests are really testing that the logic in the Func constraint is correct which can be done without passing it into the Repository.

like image 72
Luke Puplett Avatar answered Feb 15 '26 14:02

Luke Puplett


It looks like you're trying to mock an extension methods. You cannot mock extension methods in this way because they're not actually declared on the type that you are mocking.

In this case, since youre repository seems to represent a collection of things you should instead substitute a simple hardcoded collection. It's not clear how exactly you might go about it since you did not provide the source code for IRepository.

like image 35
marcind Avatar answered Feb 15 '26 15:02

marcind



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!