Moq +单元测试 - System.Reflection.TargetParameterCountException:参数计数不匹配

时间:2011-10-10 14:48:16

标签: c# wpf unit-testing moq ivalueconverter

我想使用带有多参数函数的lambda,但是当我尝试调用mock.Object.Convert(value, null, null, null);行时,Moq会在运行时抛出此异常。

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

实施它的正确方法是什么?

4 个答案:

答案 0 :(得分:126)

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

没有例外,测试通过。

答案 1 :(得分:5)

不是OP的答案,但可能是未来的googlers:

我的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签名不正确

答案 2 :(得分:1)

也许是因为你传递的是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方法。”

您希望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;
        });

答案 3 :(得分:1)

就我而言,我认为Returns<>中的类型是输出类型,但事实上它是输入类型。

所以如果你有方法

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

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

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