如何设置最小起订量以接受给定表达式 <T> 的任何实例?

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

我有以下要模拟的接口:

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

与以下 Poco:

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

然后我将模拟设置为:

[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
}

但我得到:

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

我在这里错过了什么?

不要将 It.IsAny 的结果分配给中间变量,直接使用它:

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

如果您查看 Setup 方法,它实际上需要一个 Expression 参数,Moq 分析它以确定您的意图,通过将 It.IsAny 的结果分配给一个中间变量,Moq 不会看到它能够理解的 MethodCallExpression,而是会看到 MemberExpression

这导致 Moq 实际上在实际参数和 expectedPredicate 变量之间执行相等性比较,而不是 It.IsAny 检查。