2009-01-25 17 views
33

ठीक है, मैं जानता हूँ कि राइनो Mocks में नए एएए वाक्य रचना से अधिक भ्रम की स्थिति का एक बहुत हो रही है, लेकिन मैं ईमानदारी से करने के लिए है से क्या मैं अब तक, देखा है मैं पसंद। यह बेहतर पढ़ता है, और कुछ कीस्ट्रोक पर बचाता है।राइनो Mocks - स्टब .Expect बनाम .AssertWasCalled

असल में, मैं ListController का परीक्षण कर रहा हूं जो मूल रूप से चीजों की कुछ सूचियों का प्रभारी होगा :) मैंने अंततः एक इंटरफ़ेस बनाया है जो अंततः डीएएल बन जाएगा, और यह निश्चित रूप से अब के लिए दबाया जा रहा है।

(manager परीक्षण के अंतर्गत प्रणाली है, data टोंटदार डेटा इंटरफेस है)

[Fact] 
    public void list_count_queries_data() 
    { 
     data.Expect(x => x.ListCount(1)); 
     manager.ListCount(); 
     data.VerifyAllExpectations(); 
    } 

इस परीक्षण का मुख्य उद्देश्य सिर्फ यह सुनिश्चित करें कि प्रबंधक है:

मैं निम्नलिखित कोड था वास्तव में डीएएल पूछताछ। ध्यान दें कि दाल वास्तव में भी वहाँ नहीं है, इसलिए कोई 'असली' मूल्य वापस आ रहा है ..

हालांकि, इस के बाद से मैं, उम्मीद बदलने के लिए एक वापसी मान की आवश्यकता की तरह विफल हो रहा है:

 data.Expect(x => x.ListCount(1)).Return(1); 

यह तो ठीक चलेगा, और परीक्षा उत्तीर्ण करेंगे, तथापि - क्या मुझे भ्रमित कर रहा है कि समय में इस बिंदु पर, वापसी मान कुछ भी नहीं का मतलब है। मैं इसे 100, 50, 42 में बदल सकता हूं, जो कुछ भी और परीक्षा हमेशा पास हो जाएगी?

यह मुझे परेशान करता है, क्योंकि एक परीक्षण स्पष्ट होना चाहिए और यदि अपेक्षित स्थितियों को सही नहीं मिला है तो पूरी तरह विफल होना चाहिए?

मैं करने के लिए परीक्षण बदलते हैं ("1" की उम्मीद आईडी गिनती से जुड़ा हुआ है):

[Fact] 
    public void list_count_queries_data() 
    { 
     manager.ListCount(); 
     data.AssertWasCalled(x => x.ListCount(1)); 
    } 

यह सब ठीक गुजरता है, और मैं AssertWasNotCalled करने के लिए इसे के सिर पर परीक्षण स्विच करते हैं, यह उम्मीद के रूप में विफल रहता है .. मुझे यह भी लगता है कि यह बहुत बेहतर पढ़ता है, परीक्षण के बारे में स्पष्ट है और सबसे महत्वपूर्ण रूप से पास और असफल होने की उम्मीद है!

तो, क्या मुझे पहले कोड उदाहरण में कुछ याद आ रही है? स्टब्स पर दावा करने पर आपके विचार क्या हैं? (वहाँ, कुछ रोचक चर्चा here था मैं व्यक्तिगत रूप से this response पसंद आया।

+1

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

उत्तर

52

उपयोग करने की कोशिश की है?

आप किस व्यवहार या राज्य की पुष्टि कर रहे हैं? विशेष रूप से, क्या आप यह सत्यापित कर रहे हैं कि सहयोगी (डेटा) में ListCount विधि (इंटरैक्शन आधारित परीक्षण) कहा जाता है, या क्या आप ListCount को अन्यत्र परिणाम सत्यापित करते समय परीक्षण के तहत कक्षा को चलाने के लिए एक डिब्बाबंद मूल्य वापस करना चाहते हैं (पारंपरिक राज्य आधारित परिक्षण)?

आप एक उम्मीद सेट चाहते हैं, एक नकली और एक उम्मीद का उपयोग करें: उपयोग MockRepository.CreateMock<IMyInterface>() और myMock.Expect(x => x.ListCount())

आप एक विधि ठूंठ, MockRepository.CreateStub<IMyInterface>() और myStub.Stub(x => x.ListCount()) उपयोग करना चाहते हैं।

(एक तरफ: मुझे पता है तुम stub.AssertWasCalled() mock.Expect के रूप में और यकीनन बेहतर पढ़ने वाक्य रचना के साथ ज्यादा एक ही बात को प्राप्त करने के लिए उपयोग कर सकते हैं, लेकिन मैं सिर्फ mocks & स्टब्स के बीच अंतर में ड्रिलिंग कर रहा हूँ)।

Roy Osherove has a very nice explanation of mocks and stubs.

अधिक कोड पोस्ट करें!

हमें एक पूर्ण तस्वीर की आवश्यकता है कि आप स्टब (या नकली) कैसे बना रहे हैं और परीक्षण के तहत कक्षा के संबंध में परिणाम का उपयोग कैसे किया जाता है। ListCount में इनपुट पैरामीटर है? यदि हां, तो यह क्या दर्शाता है? क्या आपको परवाह है कि यह है के साथ एक निश्चित मूल्य? क्या आपको परवाह है कि ListCount एक निश्चित मूल्य देता है?

जैसा कि साइमन लारोच ने बताया, यदि प्रबंधक वास्तव में सूचीकरण के मॉक/स्टब किए गए वापसी मूल्य के साथ कुछ भी नहीं कर रहा है, तो परीक्षण इसके कारण पास या विफल नहीं होगा। सभी परीक्षणों की उम्मीद है कि मजाक/स्टबबेड विधि कहा जाता है - और कुछ नहीं।

बेहतर, समस्या को समझने के लिए जानकारी के तीन टुकड़े पर विचार और आप जल्दी ही यह पता लगा देगा:

  1. क्या परीक्षण किया जा रहा है
  2. क्या स्थिति में?
  3. अपेक्षित परिणाम क्या है?

की तुलना करें: mocks साथ इंटरेक्शन आधारित परीक्षण। नकली पर कॉल परीक्षण है। एक ठूंठ साथ

[Test] 
public void calling_ListCount_calls_ListCount_on_DAL() 
{ 
    // Arrange 
    var dalMock = MockRepository.Mock<IDAL>(); 
    var dalMock.Expect(x => x.ListCount()).Returns(1); 
    var manager = new Manager(dalMock); 

    // Act 
    manager.ListCount(); 

    // Assert -- Test is 100% interaction based 
    dalMock.VerifyAllExpectations(); 
} 

राज्य आधारित परीक्षण। स्टब परीक्षण चलाता है, लेकिन उम्मीद का हिस्सा नहीं है।

[Test] 
public void calling_ListCount_returns_same_count_as_DAL() 
{ 
    // Arrange 
    var dalStub = MockRepository.Stub<IDAL>(); 
    var dalStub.Stub(x => x.ListCount()).Returns(1); 
    var manager = new Manager(dalMock); 

    // Act 
    int listCount = manager.ListCount(); 

    // Assert -- Test is 100% state based 
    Assert.That(listCount, Is.EqualTo(1), 
     "count should've been identical to the one returned by the dal!"); 
} 

मैं व्यक्तिगत रूप से राज्य आधारित परीक्षण के पक्ष में जहां पर सभी संभव है, हालांकि बातचीत आधारित परीक्षण अक्सर एपीआई कि मन में Tell, Don't Ask साथ डिजाइन किए हैं, जैसा कि आप कोई भी उजागर राज्य के खिलाफ सत्यापित करने के लिए की जरूरत नहीं होगी के लिए आवश्यक है!

एपीआई भ्रम। मोक्स स्टब्स नहीं है। या क्या वे?

राइनो मोक्स में एक नकली और एक स्टब के बीच भेद उलझन में है। परंपरागत रूप से, स्टब्स अपेक्षाओं के लिए नहीं हैं - इसलिए यदि आपके परीक्षण डबल में इसकी विधि नहीं है, तो यह सीधे परीक्षण विफल होने का कारण नहीं बनता है।

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

+0

+1 से मेरी पहचान के बीच भेद के लिए – Edward

+0

मैं हमेशा स्टब्स का उपयोग करके व्यवहार परीक्षण करता हूं, जैसा कि यह ऐंडे के पद में किया जाता है: http://ayende.com/blog/3384/rhino-mocks- एपीआई भ्रम के लिए 3-5-डिजाइन-निर्णय-द-रोल-ऑफ-स्टब-बनाम नकली –

+0

+1। वास्तव में मुझे क्या लगता है ... – 70sCommander

1

मुझे लगता है कि यह क्या आपके manager.ListCount (के साथ क्या करना है) वापसी मान के साथ कर रही है।

यह फिर अपने इसे का उपयोग नहीं कर रहा है दाल में कुछ भी इससे कोई फर्क नहीं होगा लौट सकते हैं।

public class Manager 
{ 
    public Manager(DAL data) 
    { 
     this.data = data 
    } 
    public void ListCount() 
    { 
     data.ListCount(1); //Not doing anything with return value 
     DoingSomeOtherStuff(); 
    }  
} 

अपनी सूची गिनती मूल्य आप तो यह क्या कर रहा है पर दावे रखना चाहिए साथ कुछ कर रहा है। उदाहरण के लिए

Assert.IsTrue(manager.SomeState == "someValue"); 
+0

+1। राइनो मोक्स के लिए भी नया हूँ। दिखाने के लिए धन्यवाद। टब। मैं .xpect का उपयोग कर रहा था क्योंकि यही सब उदाहरण था ... –

0

तुम क्या अपने परीक्षण प्राप्त करने के लिए कोशिश कर रहा है

data.AssertWasCalled(x => x.ListCount(1) = Arg.Is(EXPECTED_VALUE)); 
संबंधित मुद्दे