2009-09-17 11 views
14

मैं Moq और सीखने के लिए नया हूँ के हिस्से के रूप वापसी मान निर्दिष्ट करना।MOQ: उम्मीदों

मैं परीक्षण करने के लिए है कि एक विधि की उम्मीद मान देता है की जरूरत है। मैंने अपनी समस्या को समझाने के लिए एक साथ एक मामूली उदाहरण रखा है। इस के साथ बुरी तरह विफल रहता है:

"ArgumentException: अभिव्यक्ति के लिए एक विधि मंगलाचरण नहीं है: सी => (c.DoSomething (" जो "," ब्लॉग ", 1) =" ठीक है ")"

आप मैं गलत क्या कर रहा हूँ को सही कर सकते हैं?

[TestFixtureAttribute, CategoryAttribute("Customer")] 
public class Can_test_a_customer 
{ 
    [TestAttribute] 
    public void Can_do_something() 
    { 
     var customerMock = new Mock<ICustomer>(); 

     customerMock.Setup(c => c.DoSomething("Jo", "Blog", 1)).Returns("OK"); 

     customerMock.Verify(c => c.DoSomething("Jo", "Blog", 1)=="OK"); 
    } 
} 

public interface ICustomer 
{ 
    string DoSomething(string name, string surname, int age); 
} 

public class Customer : ICustomer 
{ 
    public string DoSomething(string name, string surname, int age) 
    { 
     return "OK"; 
    } 
} 

संक्षेप में: अगर मैं उपरोक्त के समान एक विधि का परीक्षण करना चाहता था, और मुझे पता है कि मैं वापस की उम्मीद कर रहा हूँ एक "ठीक है", मैं कैसे लिखते थे यह Moq का उपयोग कर?

किसी भी सुझाव के लिए धन्यवाद।

उत्तर

15
  1. आप एक परीक्षण विषय है कि नकली वस्तुओं के साथ सूचना का आदान प्रदान की जरूरत है (जब तक आप Moq के लिए एक नौसिखिया परीक्षण लिख रहे हैं।) मैं नकली वस्तु पर
  2. आप सेटअप अपेक्षा से कम एक सरल एक ऊपर लिखा है, सही को निर्दिष्ट तर्क (सख्त - आप बेशक, किसी और Is.Any<string> उपयोग करने के लिए किसी भी स्ट्रिंग स्वीकार करने के लिए चाहते हैं) और बदले मान निर्दिष्ट (परीक्षण के अधिनियम कदम का हिस्सा है) किसी भी
  3. आपका परीक्षण विषय अपने नकली
  4. पर फोन करेगा, तो आपको आवश्यकतानुसार परीक्षण विषय पर जोर दें। नकली विधियों से वापसी मूल्य परीक्षण विषय द्वारा उपयोग किया जाएगा - इसे परीक्षण विषय के सार्वजनिक इंटरफ़ेस के माध्यम से सत्यापित करें।
  5. तुम भी सत्यापित करें कि सभी अपेक्षाओं आपके द्वारा निर्दिष्ट मुलाकात कर रहे थे - सभी तरीकों है कि आप की उम्मीद वास्तव में कहा जाता था कहा जाता है।

[TestFixture] 
public class Can_test_a_customer 
{ 
    [Test] 
    public void Can_do_something() 
    { 
    //arrange 
    var customerMock = new Moq.Mock<ICustomer>(); 
    customerMock.Setup(c => c.DoSomething(Moq.It.Is<string>(name => name == "Jo"), 
     Moq.It.Is<string>(surname => surname == "Blog"), 
     Moq.It.Is<int>(age => age == 1))) 
     .Returns("OK"); 

    //act 
    var result = TestSubject.QueryCustomer(customerMock.Object); 

    //assert 
    Assert.AreEqual("OK", result, "Should have got an 'OK' from the customer"); 
    customerMock.VerifyAll(); 
    } 
} 

class TestSubject 
{ 
    public static string QueryCustomer(ICustomer customer) 
    { 
    return customer.DoSomething("Jo", "Blog", 1); 
    } 
} 
+1

बिल्कुल। उनके परीक्षण में कोई परीक्षण विषय नहीं है, जिसने भ्रम पैदा किया है। आप एक परीक्षण विषय का परीक्षण करते हैं, न कि नकली। –

+0

मैं भी सीख रहा हूं, मुझे लगता है कि मेरे सिर के चारों ओर लपेटा गया है, क्या आप कृपया पुष्टि करेंगे। इस उदाहरण में 'DoSomething'' jabberwocky 'वापस कर सकता है, लेकिन क्योंकि आपकी' // व्यवस्था .etup' को 'Return ("OK") 'कहा जाता है, यह दावा है। मैं समझता हूं कि परीक्षण यह सुनिश्चित करना है कि 'टेस्टसब्जेक्ट' अपेक्षित प्रदर्शन करता है, और यहां 'ग्राहक' पर कोई परीक्षण नहीं है। यदि ऐसा है, तो 'TestSubject' सफलतापूर्वक पूरा होने के सत्यापन के लिए 'ग्राहक' से वापसी मूल्य क्यों न करें 'न केवल'। (" सफलता ") या कुछ अन्य सामान्य स्ट्रिंग का दावा क्यों करें? – JabberwockyDecompiler

+0

@JabberwockyDecompiler - यह सिर्फ एक नमूना परीक्षण था जहां आउटपुट एक सहयोगी (मॉक) पर निर्भर करता है .. उदाहरण के लिए ग्राहक "सैम" वापस कर सकता है और परीक्षण के तहत विधि/वर्ग "हैलो सैम!" लौटा सकता है। इसका परीक्षण करने के लिए: आपको परीक्षण में "सैम" वापस करने के लिए नकली सेट करने की आवश्यकता होगी। – Gishu

11

Mock<T>.Verify मूल्य वापस नहीं है कि विधि कॉल लौटे, तो आप सिर्फ का उपयोग कर उम्मीद मूल्य की तुलना नहीं कर सकते "=="।

वास्तव में, no overload of Verify है जो कुछ भी लौटाता है, क्योंकि आपको कभी यह सत्यापित करने की आवश्यकता नहीं है कि एक मॉक विधि एक विशिष्ट मान देता है। आखिरकार, आप इसे उस स्थान को पहली जगह वापस करने के लिए सेट अप करने के लिए ज़िम्मेदार थे! आपके द्वारा परीक्षण किए जा रहे कोड द्वारा मॉक किए गए तरीकों के रिटर्न मानों का उपयोग किया जाना है - आप मोजे का परीक्षण नहीं कर रहे हैं।

उपयोग पुष्टि करते हैं कि विधि तर्क आप की उम्मीद के साथ बुलाया गया था सत्यापित करें, या कि एक संपत्ति एक मूल्य आप उम्मीद सौंपा गया था। जब आप अपने परीक्षण के "जोर" चरण में जाते हैं तो मॉक किए गए तरीकों और गुणों के वापसी मूल्य महत्वपूर्ण नहीं होते हैं।

2

आप एक ही बात इस आदमी यहाँ कर रहा था कर रहे हैं: How to Verify another method in the class was called using Moq

आप क्या परीक्षण कर रहे हैं आप मजाक कर रहे हैं। यह समझ में नहीं आता है। मोक्स का उपयोग अलगाव के लिए है। आपका Can_Do_Something परीक्षण हमेशा पास करेगा। कोई बात नहीं क्या। यह एक अच्छा परीक्षण नहीं है।

गिशू के परीक्षण या परीक्षण किए गए एसओ प्रश्न में प्रस्तावित परीक्षण पर नज़र डालें।

+0

हाय, आप बिल्कुल सही हैं, मैं पर मजाक करने की दुनिया में नया हूं, तो यह कहना सही है कि विधि को मॉक करना सिर्फ यह सत्यापित करना है कि विधि कहलाती है या एक विधि सेट की गई है कि यह सत्यापित करने के लिए कि विधि क्या है। क्या ये सही है? –

+1

एक नकली बाहरी विधि को सत्यापित करने के लिए डिज़ाइन की गई है और उस कोड को अलग करें जिसे आप वास्तव में * परीक्षण कर रहे हैं। उदाहरण के लिए, यदि आपकी कक्षा ने डेटाबेस तक पहुंचने का प्रयास किया है, तो आप अपने डेटा एक्सेस क्लास का नकल करेंगे ताकि न केवल यह लगातार परिणाम लौटाए, लेकिन इसलिए आपके परीक्षण को डेटाबेस चलाने की आवश्यकता नहीं थी। आप उस वर्ग को अलग कर रहे हैं जिसे आप अन्य परिवर्तनों से परीक्षण कर रहे हैं जो आप कर सकते हैं। –