MaYaN
MaYaN

Reputation: 6996

How do I setup MOQ to accept Any instances of a given Expression<T>?

I have the following interface that I want to mock:

public interface ISomeInterface
{
    string GiveMe(Expression<Func<Person, bool>> predicate);
}

With the following Poco:

public class Person
{
    public string Name { get; set; }
}

Then I am setting up my mock as:

[Test]
public void Run()
{
    var expectedPredicate = It.IsAny<Expression<Func<Person, bool>>>();
    var mock = new Mock<ISomeInterface>(MockBehavior.Strict);
    mock
        .Setup(m => m.GiveMe(expectedPredicate))
        .Returns("Yo!");

    var message = mock.Object.GiveMe(p => p.Name == string.Empty); // throws
}

But I am getting:

Invocation failed with mock behavior Strict. All invocations on the mock must have a corresponding setup.

What am I missing here?

Upvotes: 1

Views: 376

Answers (1)

Lukazoid
Lukazoid

Reputation: 19426

Don't assign the result of It.IsAny to an intermediate variable, use it inline:

mock.Setup(m => m.GiveMe(It.IsAny<Expression<Func<Person, bool>>>()))
    .Returns("Yo!");

If you look at the Setup method, it actually takes an Expression parameter, Moq analyses this to determine what your intention is, by assigning the result of It.IsAny to an intermediate variable, Moq will not see the MethodCallExpression it is capable of understanding and instead will see a MemberExpression.

This results in Moq actually performing an equality comparison between the actual parameter and expectedPredicate variable rather than the It.IsAny check.

Upvotes: 2

Related Questions