2015-05-30 8 views
5

मैं विधियों के इंटरफ़ेस के साथ जोड़ा गया Moq का उपयोग कर रहा हूं। मुझे यह जांचने की ज़रूरत है कि इस इंटरफ़ेस में विधियों को एक निश्चित अनुक्रम में निष्पादित किया गया है साथ ही प्रत्येक के लिए एक निश्चित संख्या में निष्पादित किया गया है।मॉकिंग विधि निष्पादन टाइम्स और अनुक्रम

इंटरफ़ेस

public interface IInterface 
{ 
    void MethodOne(string foo); 
    void MethodTwo(string foo); 
} 

विधि

// MyClass stuff ... 

public async Task Run() 
{ 
    MethodOne("foo"); 
    MethodTwo("foo"); 
} 

// ... 

टेस्ट

मैं यह सत्यापित करने के तरीकों को (एक बार) समय की एक निश्चित राशि क्रियान्वित कर रहे हैं इस परीक्षण में लिखा है:

[TestMethod] 
public async Task Test() 
{ 
    var mock = new Mock<IInterface>(); 
    var mockSequence = new MockSequence(); 

    var obj = new MyClass(); 
    await obj.Run(); 

    mock.Verify(i=> i.MethodOne("foo"), Times.Once()); 
    mock.Verify(i=> i.MethodTwo("foo"), Times.Once()); 
} 

यह ठीक काम करता है ...

मैंने एक निश्चित अनुक्रम निर्धारित करने के लिए इन परीक्षणों का सही प्रयास किया है, लेकिन परीक्षण हमेशा पास होता है।

[TestMethod] 
public async Task Test() 
{ 
    var mock = new Mock<IInterface>(); 
    var mockSequence = new MockSequence(); 

    var obj = new MyClass(); 
    await obj.Run(); 

    mock.InSequence(mockSequence).Setup(i => i.MethodOne("foo")); 
    mock.InSequence(mockSequence).Setup(i => i.MethodTwo("foo")); 
} 

पारित करना चाहिए, और है ...

[TestMethod] 
public async Task Test() 
{ 
    var mock = new Mock<IInterface>(); 
    var mockSequence = new MockSequence(); 

    var obj = new MyClass(); 
    await obj.Run(); 

    mock.InSequence(mockSequence).Setup(i => i.MethodTwo("foo")); // swapped order here 
    mock.InSequence(mockSequence).Setup(i => i.MethodOne("foo")); 
} 

पारित नहीं करना चाहिए, लेकिन है ...

  1. क्या मैं उचित अनुक्रम सत्यापित करने के लिए अलग तरह से करने की जरूरत पूरी की जाती है कर ?
  2. मैं दोनों को कैसे जोड़ूं ताकि मैं निष्पादन समय और उचित अनुक्रम की संख्या का परीक्षण कर सकूं?
+0

मैंने इसे डुप्लिकेट के रूप में चिह्नित किया क्योंकि दोनों प्रश्न एक ही मुद्दे को संदर्भित करते हैं। यदि वे नहीं करते हैं, तो मुझे बताएं और मैं फिर से खोलने के लिए वोट दूंगा। – dcastro

+0

मैंने यह पूछने से पहले उस प्रश्न को पढ़ा। उस सवाल को एक उत्तर के साथ हल किया गया था जिसमें कहा गया था कि यह मोक में एक बग था। वह 3 साल पहले था ... मुझे लगता है कि यह अभी भी एक बग नहीं है। – kspearrin

+0

मैंने प्रश्न – dcastro

उत्तर

4

यह आपके विषय से आगे हो सकता है लेकिन NSubstitute एक बहुत ही मज़ेदार लाइब्रेरी है जो इसे बहुत अच्छी तरह से संभालती है। NSubstitute में यह सिर्फ है:

var mock = Substitute.For<IInterface>(); 
    var obj = new MyClass(); 
    await obj.Run(); 

    Received.InOrder(() => { 
    mock.MethodOne("foo"); 
    mock.MethodTwo("foo"); 
    }); 
+0

को फिर से खोल दिया है सुझाव के लिए धन्यवाद। मैं इसे एक लुक दूंगा। ऐसा लगता है कि मोक की तुलना में बहुत बेहतर दस्तावेज़ हैं। – kspearrin

+0

हाँ और एपीआई उपयोग करने के लिए बहुत अच्छा है। –

+0

वाह, आप सही हैं। यह बेहतर तरीका है। बहुत अधिक सहज ज्ञान युक्त। मैं इसे देखने के लिए कुछ दूंगा कि कोई भी प्रश्न का उत्तर दे सकता है जो मोक के बारे में अधिक विशेष रूप से है। यदि नहीं, तो मैं इसे आपको दूंगा। – kspearrin

3

InSequence के लिए आपका उदाहरण परीक्षण गलत क्रम में होने लगते हैं। Run विधि का आह्वान करने से पहले, आपको Setup प्रदर्शन करना चाहिए। मैंने माना है कि यह एक टाइपो है और आपके वास्तविक परीक्षण Setup करते हैं, फिर ऑब्जेक्ट को सही क्रम में आमंत्रित करते हैं। यह भी स्पष्ट नहीं है कि IInterface का आपका नकल MyClass पर कैसे मिलता है। मेरे अंतिम उदाहरण में, मैंने माना है कि यह वास्तव में इंजेक्शन दिया गया है ...

Moq का InSequence समर्थन केवल तभी काम करता है जब आप सख्त मोक्स का उपयोग कर रहे हों। आप इस तरह से अपने Mock बनाते हैं:

var mock = new Mock<IInterface>(MockBehavior.Strict); 

फिर इस काम करेगा:

mock.InSequence(mockSequence).Setup(i => i.MethodOne("foo")); 
mock.InSequence(mockSequence).Setup(i => i.MethodTwo("foo")); 

जबकि इस विफल रहता है:

mock.InSequence(mockSequence).Setup(i => i.MethodTwo("foo")); // swapped order here 
mock.InSequence(mockSequence).Setup(i => i.MethodOne("foo")); 

ध्यान दें, त्रुटि आता है कि विधि एक लापता के बारे में है इसी सेटअप ... अनुक्रम से बाहर बुलाए जाने के बजाए, यदि आप इसकी अपेक्षा नहीं कर रहे हैं तो डीकोड करना सबसे आसान नहीं है।

वैकल्पिक दृष्टिकोण, यदि आप सख्त मोक्स का उपयोग नहीं करना चाहते/नहीं कर सकते हैं तो कॉलबैक का उपयोग करके अपनी अनुक्रम जांच को कार्यान्वित करना है।इस तरह कुछ:

int sequence = 1; 

mock.Setup(i => i.MethodOne("foo")) 
    .Callback(()=>Assert.AreEqual(1, sequence++, "Method called out of sequence")); 
mock.Setup(i => i.MethodTwo("foo")) 
    .Callback(() => Assert.AreEqual(2, sequence++, "Method called out of sequence")); 

var obj = new MyClass(mock.Object); 
await obj.Run(); 
संबंधित मुद्दे