Moq + 单元测试 - System.Reflection.TargetParameterCountException:参数计数不匹配
Posted
技术标签:
【中文标题】Moq + 单元测试 - System.Reflection.TargetParameterCountException:参数计数不匹配【英文标题】:Moq + Unit Testing - System.Reflection.TargetParameterCountException: Parameter count mismatch 【发布时间】:2011-12-04 14:23:38 【问题描述】:我正在尝试使用带有多参数函数的 lambda,但当我尝试调用 mock.Object.Convert(value, null, null, null);
行时,Moq 在运行时抛出此异常。
System.Reflection.TargetParameterCountException:参数计数不匹配
代码是:
var mock = new Mock<IValueConverter>();
mock.Setup(conv => conv.Convert(It.IsAny<Object>(), It.IsAny<Type>(),
It.IsAny<Object>(), It.IsAny<CultureInfo>())).Returns((Int32 num) => num + 5);
var value = 5;
var expected = 10;
var actual = mock.Object.Convert(value, null, null, null);
实现它的正确方法是什么?
【问题讨论】:
【参考方案1】:这是您的 Returns
子句。您正在设置一个 4 参数方法,但您只使用 1 参数 lambda。我运行以下没有问题:
[TestMethod]
public void IValueConverter()
var myStub = new Mock<IValueConverter>();
myStub.Setup(conv => conv.Convert(It.IsAny<object>(), It.IsAny<Type>(), It.IsAny<object>(), It.IsAny<CultureInfo>())).
Returns((object one, Type two, object three, CultureInfo four) => (int)one + 5);
var value = 5;
var expected = 10;
var actual = myStub.Object.Convert(value, null, null, null);
Assert.AreEqual<int>(expected, (int) actual);
无异常,测试通过。
【讨论】:
我打算询问这是否是对框架的测试,但我想我会怀疑可能是尝试让 Mock 到的临时代码举止得体。 我想也是,但它还是让我笑了。 我听到了。当我执行代码时,我想“是的,框架库仍在工作”。 :)【参考方案2】:不是 OP 的答案,但也许是未来的谷歌人的答案:
我的Callback
与正在设置的方法的签名不匹配
Mock
.Setup(r => r.GetNextCustomerNumber(It.IsAny<int>()))
.Returns(AccountCounter++)
.Callback<string, int>(badStringParam, leadingDigit =>
// Doing stuff here, note that the 'GetNextCustomerNumber' signature is a single int
// but the callback unreasonably expects an additional string parameter.
);
这是一些重构的结果,重构工具当然无法意识到Callback
签名不正确
【讨论】:
哇,在我读到你的帖子之前,我一直在努力解决同样的问题,并且一直在掩盖回调。非常有帮助,我很高兴你发布它。 这也是我的问题。我为方法添加了一个参数,修复了 Setup() 调用,但错过了 Callback() 参数。【参考方案3】:也许是因为您传递了null
但It.IsAny<Object>()
期待任何object
除了null
?如果您执行以下操作会发生什么?:
var actual = mock.Object.Convert(value, new object(), typeof(object), CultureInfo.CurrentCulture);
这只是我在黑暗中的一个刺,我更熟悉Rhino.Mocks。
我的第二个猜测:
查看了下载附带的 Moq.chm,
您正在使用 Setup(Expression<Action<T>>)
方法,该方法“指定模拟类型的设置以调用 void
方法。”
您希望 Setup<TResult>(Expression<Func<T,TResult>>)
方法“指定模拟类型的设置以调用值返回方法”。
所以你可以试试:
mock.Setup<Int32>(
conv =>
conv.Convert(
It.IsAny<Object>(),
It.IsAny<Type>(),
It.IsAny<Object>(),
It.IsAny<CultureInfo>());
return num + 5;
);
【讨论】:
mock.Setup在我的例子中,我认为Returns<>
中的类型是输出类型,但实际上它是输入类型。
如果你有方法
public virtual string Foo(int a, int b) ...
正确的子句是.Returns<int, int>(...)
,而不是我最初想的.Returns<string>(...)
。
我的错误是因为我最初测试的是具有相同输入和返回类型的函数 - 例如public virtual string Foo(string a)
。
【讨论】:
以上是关于Moq + 单元测试 - System.Reflection.TargetParameterCountException:参数计数不匹配的主要内容,如果未能解决你的问题,请参考以下文章