2011-10-10 47 views
61

我打算使用具有多参数函数的lambda,但Moq在运行时抛出此异常,当我尝试调用mock.Object.Convert(value, null, null, null);行时。Moq +单元测试 - System.Reflection.TargetParameterCountException:参数计数不匹配

System.Reflection.TargetParameterCountException: Parameter count mismatch

的代码是:

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); 

什么来实现它的正确方法?

回答

108

这是你的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); 
} 

没有例外,测试通过。

+0

我打算询问这是否是对框架的测试,但我想我会给出疑问的好处,也许这是临时代码,试图让模拟行为正常。 –

+0

我认为它也是,但它让我无论如何都笑了起来。 –

+0

我听到你。当我执行代码时,我认为“yup,框架库仍在工作。” :) –

2

也许是因为你逝去的nullIt.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方法“。

你想te 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; 
     }); 
+0

mock.Setup 推断返回类型为Object,因为Convert方法返回一个Object。 –

4

不为OP,但也许对未来的Google答案:

我有一个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签名是不正确的

+0

哇,我正在抨击我的头反对这个相同的问题,并保持在回调直到我读你的帖子。非常有帮助,我很高兴你发布它。 – dblood

1

在我的情况下,我认为Returns<>中的类型是输出类型,但实际上它是输入类型。

所以,如果你有一个方法

public virtual string Foo(int a, int b) { ... } 

正确的条款是.Returns<int, int>(...),NOT .Returns<string>(...)这是我的想法最初。

我的错误是因为我最初测试的是具有相同输入和返回类型的函数 - 例如public virtual string Foo(string a)