繁体   English   中英

Moq设置将所有空的枚举/数组视为相同的参数

[英]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);

我所期望的是从这些调用中获取value1value2 ,但实际上后者调用会覆盖第一个调用,而我只从两个调用中获得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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM