首页 > 解决方案 > 模拟存根和起订量设置的行为不同?Moq 中存根的等价物是多少?

问题描述

我在两个不同的项目中编写单元测试时意识到,Moq 中的设置行为与 Rhino-Mocks 中的 Stub 不同。

一类使用 Mock,它具有我存根的这些场景之一

for (int i=0; i<ObjectAList.Count; i++)
{
     _translator.Stub(x => x.TranslateToObjectB(ObjectAList[i])).Return(ObjectBList[i]);
}

上面的例子就像一个魅力。

但是当我尝试在另一个使用 Moq 的项目中做同样的事情时,使用设置,它失败了。

for (int i=0; i<ObjectAList.Count; i++)
{
     _translator.SetUp(x => x.TranslateToObjectB(ObjectAList[i])).Returns(ObjectBList[i]);
}

相反,我不得不做这样的事情,

int i = 0;
foreach (var ObjectA in ObjectAList)
{
     _translator.Setup(x => x.ConvertToProcessingFilter(ObjectA)).Returns(ObjectBList[i]);
     i++;
}

我只是在寻找存根与设置行为如此不同的原因。如果这是设置的预期,那么在 Moq 中存根的等价物是什么?

标签: c#unit-testingmoqrhino-mocks

解决方案


您所看到的与Closures 在forforeachloops中的行为不同有关。

和:

for (int i=0; i<ObjectAList.Count; i++)
{
     _translator.Setup(x => x.TranslateToObjectB(ObjectAList[i])).Returns(ObjectBList[i]);
}

您正在关闭(捕获)for迭代变量。行为将取决于模拟框架何时评估 lambda 表达式。

尝试:

for (int i=0; i<ObjectAList.Count; i++)
{
     var j = i;
     _translator.Setup(x => x.TranslateToObjectB(ObjectAList[j])).Returns(ObjectBList[j]);
}

反而。它会起作用吗?

您也可以只进行一项设置,类似于以下内容:

_translator.Setup(x => x.TranslateToObjectB(It.IsAny<ObjAType>()))
  .Returns((ObjAType a) => ObjectBList[ObjectAList.IndexOf(a)]);

推荐阅读