2009-10-29 42 views
31

इस वर्ग पर विचार करें:Moq - सत्यापित करने के लिए कैसे एक संपत्ति के मूल्य सेटर के माध्यम से सेट कर दिया जाता है कि

public class Content 
{  
    public virtual bool IsCheckedOut {get; private set;} 
    public virtual void CheckOut() 
    { 
     IsCheckedOut = true; 
    } 

    public virtual void CheckIn() 
    { 
     //Do Nothing for now as demonstrating false positive test. 
    } 
} 

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

[TestMethod] 
public void CheckOutSetsCheckedOutStatusToTrue() 
{ 
    Content c = new Content();  
    c.CheckOut(); 
    Assert.AreEqual(true, c.IsCheckedOut); //Test works as expected 
} 

[TestMethod] 
public void CheckInSetsCheckedOutStatusToFalse() 
{ 
    Content c = new Content(); 
    c.CheckIn(); 
    Assert.AreEqual(false, c.IsCheckedOut); //Test does not work as expected 
} 

दूसरा परीक्षण गलत कारणों से गुजरता है। तो मैं यह जांचने के लिए मॉकिंग (moq) का उपयोग कैसे कर सकता हूं कि चेकइन IscheckedOut प्रॉपर्टी सेट कर रहा है?

धन्यवाद।

संपादित

स्पष्ट करने के लिए: मैं) एक विधि चेकइन (बुलाया जिनका काम यह गलत पर IsCheckedOut स्थिति स्थापित करने के लिए है।

आप मेरे टेस्ट कोड में देखेंगे कि टेस्ट वापस लौटाएगा भले ही मैं संपत्ति मूल्य को गलत पर सेट न करूं; यह उम्मीद है, यहां कुछ भी गलत नहीं है।

मुझे लगता है कि मेरा प्रश्न विशेष रूप से यह है कि मैं कैसे सत्यापित कर सकता हूं कि CheckIn() विधि ने IscheckedOut प्रॉपर्टी को गलत पर सेट किया है? यही वह है जिसे मैं व्यवहारिक सत्यापन कहूंगा।

मुझे विश्वास है कि कुछ टिप्पणियों ने राज्य सत्यापन के लिए कुछ ऐसा करने का सुझाव दिया है? यदि ऐसा है तो मैं नहीं मानता कि सब पर इस हिस्से मजाक में किसी भी मूल्य नहीं होता है हम बस का उपयोग कर सकते हैं जब:

Content c = new Content();  
c.CheckIn();  
Assert.AreEqual(false, c.IsCheckedOut); //State verification 
बेशक

मैं गलत हो सकता है, तो मदद कृपया मुझे इन अवधारणाओं :)

+0

यह वास्तव में Ischecked आउट संपत्ति के उद्देश्य पर निर्भर करता है - यदि यह वस्तु का व्यवहार है कि कुछ चेक इन करने के बाद चेक किया गया है तो गलत है तो आपके ऊपर क्या है ठीक है। यदि संपत्ति एक बड़ी व्यवहार की जांच करने के लिए आपकी कक्षा में एक खिड़की है तो वह वही होगा जो मैं राज्य सत्यापन कहूंगा। तो ... वास्तव में इरादे पर निर्भर करता है। – FinnNk

+0

इस समस्या को हल करने लग रहा था: http://stackoverflow.com/questions/2853313/moq-how-to-correctly-mock-set-only-properties –

+0

सीधे सवाल का जवाब नहीं है, लेकिन मैं यह जांचने के लिए आवश्यक है कि एक संपत्ति स्पष्ट रूप से सत्य पर सेट की गई थी: 'mock.SetupProperty (foo => foo.SomeProperty);/* परीक्षण परीक्षण कार्रवाई * /; mock.VerifySet (foo => foo.SomeProperty = it.IsAny (), "कुछ प्रॉपर्टी सेट होनी चाहिए"); Assert.True (mock.Object.SomeProperty, "कुछ प्रॉपर्टी को सत्य पर सेट किया जाना चाहिए था"); –

उत्तर

33

स्पष्ट निम्नलिखित काम करना चाहिए।

var mock=new Mock<IContent>(); 
mock.SetupSet(content => content.IsCheckedOut=It.IsAny<bool>()).Verifiable(); 

और परीक्षण कोड के बाद: के रूप में अपने नकली वस्तु कॉन्फ़िगर

mock.VerifySet(content => content.IsCheckedOut=It.IsAny<bool>()); 

मैं इसे किसी भी तरह का परीक्षण नहीं किया है, तो कृपया मुझे बताओ कि वह आपके लिए काम करता है।

संपादित करें। वास्तव में, यह काम नहीं करेगा क्योंकि IsCheckedOut के लिए सेटटर गलत है।

वैसे भी, अब मैं देखता हूं कि आपने कभी भी कक्षा निर्माण समय पर IsCheckedOut का मान निर्धारित नहीं किया है। - आम तौर पर आप, ऊपर कुछ की स्थापना की जानी चाहिए एक क्रिया करने और फिर

public Content() 
{ 
    IsCheckedOut=false; 
} 
+0

स्पष्टीकरण के लिए।मैं IscheckedOut प्रॉपर्टी पर सेटटर का परीक्षण नहीं करना चाहता, इसके बजाय मैं यह जांचना चाहता हूं कि विधि CheckIn() ने IsCheckedOut = false सेट किया है; इसके अलावा, IscheckedOut संपत्ति निजी है, इसलिए मुझे नहीं लगता कि सेटअप काम करेगा। क्या मैं ऐसा करना चाहता हूं जो मैं करना चाहता हूं? कोई और विचार? –

+0

IsCheckedOut आपके इंटरफ़ेस में है, इसलिए यह निजी नहीं हो सकता है? – FinnNk

+0

फिननक: केवल गेटर इंटरफ़ेस में है, सेटर निजी है। – Konamiman

2

मैं सुझाव दे सकते हैं कि आप गलत तरीके से इस बारे में सोच रहे होंगे: यह Content वर्ग के लिए निम्न जोड़ने के लिए एक अच्छा विचार होगा व्यवहार की जांच (परिणाम)। इस मामले में यह वास्तव में मायने रखता है कि यह सेटटर द्वारा गलत पर सेट नहीं किया गया था - इससे कोई फर्क नहीं पड़ता कि किसी दिए गए परिदृश्य के बाद यह गलत है। यदि आप अलगाव में परीक्षण लेते हैं तो यह थोड़ा अजीब लग सकता है, लेकिन कुछ भी आपके परीक्षण सेट में मौजूद होगा।

यदि आप दो वर्गों के बीच बातचीत का परीक्षण कर रहे थे तो स्थिति अलग होगी - फिर संपत्ति सेटटर पर एक अपेक्षा स्थापित करना ठीक होगा - क्योंकि सेटिंग कार्रवाई आप जिस इंटरैक्शन का परीक्षण कर रहे हैं।

मैं Moq से परिचित नहीं हूं क्योंकि मैं Rhino.Mocks का उपयोग करता हूं - लेकिन मुझे लगता है कि नकली लाइनों के साथ कुछ होगा। VerifySet (content => content.IscheckedOut = It.IsEqual (true)) ;

+0

कृपया मेरी संपादित पोस्ट देखें :) –

4

क्यों आप बस शुरू करने के लिए चेक आउट करने के लिए सामग्री सेट अप नहीं करते हैं? याद रखें, आप केवल चेकइन फ़ंक्शन के व्यवहार का परीक्षण कर रहे हैं।

[TestMethod] 
public void CheckInSetsCheckedOutStatusToFalse() 
{ 
    // arrange - create a checked out item 
    Content c = new Content(); 
    c.CheckOut(); 

    // act - check it in 
    c.CheckIn(); 

    // assert - IsCheckedOut should be set back to false 
    Assert.AreEqual(false, c.IsCheckedOut); 
} 
+2

मैं मानता हूं कि एक नकली (आईएनजी ढांचे) का उपयोग इस मामले में नस्लीय महसूस नहीं करता है। यह सुझाया गया तरीका बेहतर है क्योंकि यह आंतरिक विवरणों के बजाय सार्वजनिक इंटरफ़ेस का परीक्षण करता है (यानी संपत्ति कैसे सेट की जाती है)। – Cellfish

12
Mock mockContect = new Mock<Cotent>(); 
mockContent.VerifySet(x => x.IsCheckedOut, Times.Once()); 

कि चाल करना होगा? यह सुनिश्चित नहीं है कि कैसे निजी सेटर खेलने के लिए आता है जैसा कि परीक्षण किया गया है। लेकिन मेरे सार्वजनिक सेटटर के लिए काम करता है।

से समझे: http://www.codethinked.com/post/2009/03/10/Beginning-Mocking-With-Moq-3-Part-2.aspx

0

मैं आपसे सहमत हूँ: क्योंकि यह परीक्षण करने के लिए (परीक्षण के अंतर्गत) अपने वर्ग और दुनिया के बाकी के बीच संपर्क के परीक्षण करने के लिए, नहीं करना है मजाक इस परिदृश्य में कोई मूल्य नहीं है आपकी कक्षा का आंतरिक तंत्र।

मुझे लगता है कि इस परीक्षण

Content c = new Content();  
c.CheckIn();  
Assert.AreEqual(false, c.IsCheckedOut); //State verification 

आपके द्वारा लिखा समझ है और यह एक झूठी सकारात्मक नहीं है! आपको यह सुनिश्चित करना होगा कि चेकइन के बाद राज्य इस तरह से क्यों है, इस पर ध्यान दिए बिना; यदि भविष्य में आप राज्य को कन्स्ट्रक्टर (या अन्य तरीकों से) में सेट करेंगे तो यह परीक्षण आपको बचाएगा और आपको चेकइन विधि को लागू करने के लिए मजबूर किया जाएगा!

कुछ मामलों में आपके जैसे ही मैं प्रारंभिक स्थिति को यह सुनिश्चित करने के लिए सेट करना चाहता हूं कि मैं चेकइन विधि को लागू करना न भूलूं; इस मामले में मैं 2 विधियों का उपयोग करता हूं (पहला बहुत बदसूरत है):

  1. मैं c.CheckInut() से पहले c.CheckOut() को कॉल करता हूं; यह बहुत बदसूरत है, क्योंकि आप 2 एक की जगह तरीकों का परीक्षण ... लेकिन मैं स्वीकार करते हैं कि मैं इसी तरह की कई बार कुछ लिखा था :-)
  2. मैं निजी सेटर संरक्षित करना, और मैं एक परीक्षण वर्ग लिखते हैं कि inherits परीक्षा के तहत कक्षा से; विधि अपना काम कर रही है यह सुनिश्चित करने के लिए इस तरह से मैं संपत्ति को सत्य पर कॉल करने से पहले सत्य पर सेट कर सकता हूं।

    public class Content2 
    { 
        public virtual bool IsCheckedOut { get; protected set; } 
        public virtual void CheckOut() 
        { 
         IsCheckedOut = true; 
        } 
    
        public virtual void CheckIn() 
        { 
         //Do Nothing for now as demonstrating false positive test. 
        } 
    } 
    
        [TestClass] 
    public class Content2Test : Content2 
    { 
        [TestMethod] 
        public void CheckOutSetsCheckedOutStatusToTrue() 
        { 
         this.CheckOut(); 
         Assert.AreEqual(true, this.IsCheckedOut); //Test works as expected 
        } 
    
        [TestMethod] 
        public void CheckInSetsCheckedOutStatusToFalse() 
        { 
         this.IsCheckedOut = true; 
         this.CheckIn(); 
         Assert.AreEqual(false, this.IsCheckedOut); //Test does not work as expected 
        } 
    } 
    

    आशा मदद करने के लिए:

यहाँ यह कोड है।

संबंधित मुद्दे