分配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/