2011-10-10 24 views
61

मैं एक बहु-पैरा फ़ंक्शन के साथ लैम्ब्डा का उपयोग करने की कोशिश कर रहा हूं लेकिन जब मैं 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); 

इसे लागू करने के लिए उचित तरीका क्या है?

उत्तर

108

यह अपने Returns खंड है। आपके पास एक 4 पैरामीटर विधि है जिसे आप सेट अप कर रहे हैं, लेकिन आप केवल 1 पैरामीटर लैम्ब्डा का उपयोग कर रहे हैं। मैं बिना किसी मुद्दे के निम्नलिखित चला गया:

[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

मैं सुना है। जब मैंने कोड निष्पादित किया, तो मैंने सोचा "हाँ, ढांचे के पुस्तकालय अभी भी काम कर रहे हैं।" :) –

2

शायद यह है क्योंकि आप गुजर रहे हैं null लेकिन It.IsAny<Object>()null को छोड़कर किसी भी object उम्मीद कर रही है है? यदि आप निम्न ?:

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

यह मैं से अंधेरे में सिर्फ एक चाकू है, मैं Rhino.Mocks से अधिक परिचित हूँ तो क्या होगा।


मेरे 2 अनुमान:

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

mock.Setup ऑब्जेक्ट के रूप में वापसी प्रकार का अनुमान लगाता है क्योंकि कनवर्ट विधि ऑब्जेक्ट देता है। –

4

नहीं ओपी के लिए लेकिन शायद भविष्य Googler के लिए एक जवाब:

मैं एक 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>(...).Returns<string>(...) है जो मैं शुरू में सोचा है, नहीं।

मेरी गलती इसलिए थी क्योंकि मैं उसी इनपुट और रिटर्न प्रकार के साथ एक फ़ंक्शन का परीक्षण कर रहा था - उदाहरण के लिए public virtual string Foo(string a)