为什么在 Moq 中使用非内联 It.IsAny<T> 无法正常工作?

Why does using an non-inlined It.IsAny<T> in Moq not work correctly?

It.IsAny<T>() 分配给变量以在模拟对象的 Setup 中使用无法按预期工作:下面显示的测试失败。

但是,如果我内联 anyString 变量,测试就会通过。这是怎么回事?

public class MyService
{
    private readonly IDependency _dependency;

    public MyService(IDependency dependency)
    {
        _dependency = dependency;
    }

    public string UseTheDependency(string input)
    {
        return _dependency.GetValue(input);
    }
}

public interface IDependency
{
    string GetValue(string input);
}

public class Tests
{
    [Test]
    public void TestTheTestClass()
    {
        var mockDependency = new Mock<IDependency>();
        var anyString = It.IsAny<string>();
        mockDependency.Setup(x => x.GetValue(anyString)).Returns("expected value");
        var service = new MyService(mockDependency.Object);
        var result = service.UseTheDependency("something random");
        Assert.That(result, Is.EqualTo("expected value"));
    }
}

这是因为 Setup 方法采用 Linq 表达式 (Expression<Func<IDependency, string>>) 作为参数,而不是委托 (Func<IDependency, string>)。它允许 Moq 检查抽象语法树以了解正在配置的调用。如果您使用在表达式外声明的变量,Moq 不知道您使用了 It.IsAny,它只会看到 null(从技术上讲,它会看到对 anyString 字段的访问封装捕获的局部变量的对象,并且该字段仅包含 null).