2011-10-10 149 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)