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

标签 c# moq

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


编辑:我很久以前就写了这个答案,现在我意识到它部分不正确。我一直是 FakeItEasy 的维护者(另一个模拟库)很多年了,它使用类似于 Moq 的方法,所以现在我对它有了更好的理解......

这不是真的 It.IsAny永远不应该被执行;它被执行,并产生一个参数约束。但只有在评估 Setup 中的调用表达式时才会捕获该约束。 ,当 Moq 具有该约束的上下文时。如果您调用It.IsAny外线调用Setup ,当没有上下文时,生成的约束不会被捕获,而只是被丢弃。

关于c# - 为什么在 Moq 中使用非内联 It.IsAny<T> 无法正常工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33669722/

相关文章:

c# - AutoFixture AutoMoq 不为某些属性创建模拟

moq - 新手尝试将 Moq 用于可枚举方法

c# - 如何使用 MoQ 和 NUnit 在 WebAPI 2 中为 ExceptionHandler 编写单元测试

c# - 未找到 View 'Index' 或其母版

c# - 奇怪的错误 - C# 应用程序

c# - 模拟函数未返回预期值

c# - 无法初始化模拟类的成员

c# - 如何 : Taking photos in windows mobile without CameraCaptureDialog?

c# - 可以优化掉的测试代码

c# - 复制 Azure Blob 及其元数据