【问题标题】:Moq setups and closures起订量设置和关闭
【发布时间】:2013-08-12 16:26:33
【问题描述】:

使用最小起订量,我试图设置一个方法来根据参数返回一些东西。 所以,如果你传递argument1,你会得到result1,如果你传递argument2,你会得到result2:

var obj = "";

var propertyMock1 = new Mock<PropertyInfo>();
var propertyMock2 = new Mock<PropertyInfo>();

var result1 = "";
var result2 = "";

var factoryMock = new Mock<IFactory>();
factoryMock.Setup(f => f.Create(obj, propertyMock1.Object)).Returns(result1);
factoryMock.Setup(f => f.Create(obj, propertyMock2.Object)).Returns(result2);

但是,当我调用factoryMock.Object.Create(obj, propertyMock1.Object) 时,返回值为null。 如果我通过propertyMock2.Object,它将按预期工作。

我不知道为什么第一个设置不起作用。

ReSharper 给了我一些提示,但我不明白。 在第一个设置中,它显示“隐式捕获的闭包:property2”,而在第二个设置中,它显示“隐式捕获的闭包:property1”。

为什么每个 lambda 都会捕获另一个 lambda 的参数?他们甚至有什么关系? 为什么第一个设置不起作用?

【问题讨论】:

  • 确定与您粘贴的代码完全相关吗?例如,您的代码中没有“property2”。
  • 如何调用Create() 方法?被测试的代码用两个不同的模拟值调用同一个模拟类似乎不太可能。您是否有以序列或数组或两个并排的 PropertyInfos 传递的构造函数注入?请参阅下面的答案以获取可能的解决方案。
  • @BartoszKP:我的错,我的意思是“propertyMock2”。
  • @KeithPayne:被测类接受一个对象,读取其属性,然后使用工厂为每个属性创建另一个对象。

标签: c# unit-testing closures moq


【解决方案1】:

还有另一种方法可以设置模拟方法以对不同的输入做出不同的反应:

var obj = "";

var propertyMock1 = new Mock<PropertyInfo>();
var propertyMock2 = new Mock<PropertyInfo>();

var result1 = "";
var result2 = "";

var factoryMock = new Mock<IFactory>();
factoryMock.Setup(f => f.Create(It.IsAny<string>(), It.IsAny<PropertyInfo>())).Returns<string, PropertyInfo>((s, pi) => {
    if (pi == propertyMock1.Object)
        return result1;
    if (pi == propertyMock2.Object)
        return result2;
});

// factoryMock.Setup(f => f.Create(obj, propertyMock2.Object)).Returns(result2);

我总是要提醒自己,还有其他包含泛型类型的 Returns。

【讨论】:

  • 实际调用 Create 方法时出现异常:System.Reflection.TargetParameterCountException : Parameter count mismatch.
  • 编辑以考虑第一个参数。
猜你喜欢
  • 2012-08-26
  • 2010-11-30
  • 1970-01-01
  • 2019-08-19
  • 1970-01-01
  • 2010-11-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多