[英]Moq setup treats all empty enumerables/arrays as the same parameter
我有一个接受IEnumerable
的方法:
MyMethod(IEnumerable<MyClass> myParameter)
现在我正在编写此代码来模拟服务:
var array1 = new MyClass[0];
var array2 = new MyClass[0];
_service
.Setup(s => s.MyMethod(array1))
.Returns(value1);
_service
.Setup(s => s.MyMethod(array2))
.Returns(value2);
最后,我正在对服务进行两次调用,两个数组都在被测系统中:
_service.MyMethod(array1);
_service.MyMethod(array2);
我所期望的是从这些调用中获取value1
和value2
,但实际上后者调用会覆盖第一个调用,而我只从两个调用中获得value2
。
这是Moq中的一个错误还是这个功能设置将IEnumerable
视为一个单独的对象而是尝试扩展它并比较所有元素或某些东西(导致两个空数组是相同的设置调用)?
当您使用Moq在方法上创建多个设置时,除非设置是有条件的(它们在参数上指定了某些条件),否则每个后续设置都将替换先前的设置。 看到这个答案 。
您可以通过指定参数必须与您要传递的参数匹配来修复代码:
[Test]
public void MyTest()
{
var service = new Mock<MyClass>();
var array1 = new MyClass[0];
var array2 = new MyClass[0];
var value1 = "value1";
var value2 = "value2";
service.Setup(s => s.MyMethod(It.Is<IEnumerable<MyClass>>(e => e == array1))).Returns(value1);
service.Setup(s => s.MyMethod(It.Is<IEnumerable<MyClass>>(e => e == array2))).Returns(value2);
Assert.AreEqual(value1, service.Object.MyMethod(array1));
Assert.AreEqual(value2, service.Object.MyMethod(array2));
}
您描述的行为是moq
的默认行为,您可以在此处看到它。 它确实展开了可枚举并调用IEnumerable.SequenceEqual
。 但是,这是默认行为(如果使用实例设置, Constant
匹配器),您可以覆盖它。 一种方法是欧文建议使用It.Is<T>
匹配器,例如
service.Setup(s => s.MyMethod(It.Is<IEnumerable<MyClass>>(e => e == array1)))
service.Setup(s => s.MyMethod(It.Is<IEnumerable<MyClass>>(e => e == array2)))
请注意, ==
默认情况下执行ReferenceEquals()
,这样就可以进行不同的不可覆盖设置。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.