【问题标题】:Moq + Unit Testing - System.Reflection.TargetParameterCountException: Parameter count mismatchMoq + 单元测试 - System.Reflection.TargetParameterCountException:参数计数不匹配
【发布时间】: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);

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

【问题讨论】:

    标签: c# wpf unit-testing moq ivalueconverter


    【解决方案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】:

    也许是因为您传递了nullIt.IsAny&lt;Object&gt;() 期待任何object 除了null?如果您执行以下操作会发生什么?:

    var actual = mock.Object.Convert(value, new object(), typeof(object), CultureInfo.CurrentCulture);
    

    这只是我在黑暗中的一个刺,我更熟悉Rhino.Mocks。


    我的第二个猜测:

    查看了下载附带的 Moq.chm,

    您正在使用 Setup(Expression&lt;Action&lt;T&gt;&gt;) 方法,该方法“指定模拟类型的设置以调用 void 方法。”

    您希望 Setup&lt;TResult&gt;(Expression&lt;Func&lt;T,TResult&gt;&gt;) 方法“指定模拟类型的设置以调用值返回方法”。

    所以你可以试试:

    mock.Setup<Int32>(
        conv => {
            conv.Convert(
                It.IsAny<Object>(), 
                It.IsAny<Type>(),
                It.IsAny<Object>(), 
                It.IsAny<CultureInfo>());
            return  num + 5;
            });
    

    【讨论】:

    • mock.Setup 将返回类型推断为 Object,因为 Convert 方法返回一个 Object。
    【解决方案4】:

    在我的例子中,我认为Returns&lt;&gt; 中的类型是输出类型,但实际上它是输入类型。

    如果你有方法

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

    正确的子句是.Returns&lt;int, int&gt;(...),而不是我最初想的.Returns&lt;string&gt;(...)

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

    【讨论】:

      猜你喜欢
      • 2016-09-21
      • 1970-01-01
      • 2019-08-07
      • 1970-01-01
      • 2020-02-13
      • 1970-01-01
      • 2011-11-17
      • 1970-01-01
      • 2022-12-08
      相关资源
      最近更新 更多