2012-02-22 8 views
6

Mockito का उपयोग करते समय, मैं केवल यह निर्भरता बाहर उपहास करने के लिए, यानी मेरी कार्यप्रवाह लग रहा है ज्यादातर इस तरह का उपयोग करें:Mockito - लग रहा है कि मैं अपनी पूरी क्षमता का उपयोग नहीं करते

:

मैं निर्भरता के साथ एक वर्ग है

public class C { 
    public C (A a, B b) { 
     this.a = a; 
     this.b = b; 
    } 

    public String fooBar() { 
     return a.foo() + b.bar(); 
    } 
} 

अपने परीक्षण कक्षा में, मैं उन निर्भरता बाहर नकली है, और उन्हें बताओ जो जब कुछ निर्दिष्ट पद्धतियों को बुलाया जाता लौटने के लिए महत्व देता है:

public class CSpec { 
    private A a = mock(A.class); 
    private B b = mock(B.class); 

    @Test 
    public itShouldReturnFooBar() { 
     when(a.foo()).thenReturn("foo"); 
     when(b.bar()).thenReturn("bar"); 

     C c = new C(a, b); 

     assertThat(c.fooBar().isEqualTo("foobar")); 
    } 
} 

(मुझे आशा है कि इस उदाहरण भी आसान या बहुत deriv नहीं है ईडी ;-))। यह ठीक काम करता है, यह मुझे अलगाव में कक्षाओं (यहां: सी) का परीक्षण करने की अनुमति देता है। फिर भी, मैंने कभी मॉकिटो की verify विधियों या इसकी किसी भी अन्य सुविधाओं का उपयोग नहीं किया। क्या यह मॉकिटो का उपयोग करने के लिए ठीक है/पर्याप्त है?

उत्तर

5

सत्यापित करें कि आमतौर पर यह जांचने के लिए उपयोग किया जाएगा कि आपका C वास्तव में एफ़ू() और बीबार() विधियों को कॉल करता है। तो आप

verify(a).foo(); 
verify(b).foo(); 

जोर से पहले या बाद में जोड़ सकते हैं। मुझे तुम्हारी जरूरत है नहीं लगता है या उन्हें यहाँ का उपयोग करना चाहिए लेकिन कई स्थितियों में, जहां आप की आवश्यकता होगी देखते हैं कि:

  • एक या ख कुछ है कि सी के सार्वजनिक एपीआई से दिखाई दे रहा/पहुंच योग्य नहीं है (उदाहरण के प्रवेश के लिए)
  • करता है
  • आप a.foo को,
  • तुम्हें यकीन कि केवलa.foo और b.bar पद्धतियों को बुलाया जाता बनाना चाहते निष्पादन के आदेश, आप जासूस के रूप में उन mocks इस्तेमाल कर सकते हैं a.foo2
  • की तरह और कुछ नहीं के साथ संबंध रहे हैं ताकि कहेंगे ख ई फिर aReal.foo
+1

लेकिन क्या यह वास्तव में मुझे कुछ खरीदता है? वापस लौटाए गए मूल्य की जांच नहीं कर रहा है? – helpermethod

+0

क्या होगा यदि आपकी विधि कोई मान वापस नहीं लाती है? – blank

+2

आपके बहुत ही साधारण मामले में हाँ, लेकिन कई मामलों में यह जांचना कि जटिल विधि के निष्पादन के दौरान वास्तव में कुछ कहा जाता है, वही है जो आप चाहते हैं। – vertti

1

हाँ, इस परीक्षण में कोई समस्या नहीं है, यह बिल्कुल ठीक है। सरल तथ्य यह है कि स्टब्स का उपयोग किया जा रहा है परीक्षण करते हैं, अगर आप स्टब्स को हटाते या बदलते हैं तो परीक्षण काम नहीं करेगा।

सत्यापित कथन जोड़ना इस तरह के परीक्षणों में चीजों को अनावश्यक बना देगा।

हालांकि यदि आप वाकई तर्क, ऑर्डर या इंटरैक्शन की संख्या या कुछ और सत्यापित करना चाहते हैं तो आप निश्चित रूप से परीक्षण ऑब्जेक्ट और उसके सहयोगियों के बीच बातचीत पर चेक जोड़ना चाहते हैं।

1

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

एक और छोटा सा उदाहरण:

public void eitherAorB() { 
    if(somethingIsTrue) { 
     a.doSomething(); 
    } else { 
     b.doSomethingElse(); 
    } 
} 

आपको लगता है कि उम्मीद विधि की उम्मीद वस्तु पर कहा जाता है सुनिश्चित करने के लिए, चाहते हो सकता है।

@Test 
public doSomethingShouldBeCalledOnA() { 
    A a = mock(A.class); 
    C c = new C(a, new B()); 

    c.setSomeThingIsTrue(true); 
    eitherAorB(); 

    verify(a).doSomething(); 
} 

@Test 
public doSomethingElseShouldBeCalledOnB() { 
    B b = mock(B.class); 
    C c = new C(new A(), b); 

    c.setSomeThingIsTrue(false); 
    eitherAorB(); 

    verify(b).doSomethingElse(); 
} 

अन्य मामलों में आप जानना चाहेंगे कि कौन सा पैरामीटर एक विधि में पारित किया गया था। इसके लिए आपको एक ArgumentCaptor की आवश्यकता है।

या कुछ मामलों में आपको वास्तविक विधि को कॉल करने या वास्तविक वस्तु (कोई नकली) का उपयोग करने की आवश्यकता नहीं है, इसलिए यह किसी ऑब्जेक्ट पर जासूसी करने और तर्कों को कैप्चर करने या व्यवहार को सत्यापित करने का समय है।

तो मॉकिटो के लिए बहुत कुछ है जो आपको थोड़ी देर में आवश्यकता हो सकती है।

2

verify दृष्टिकोण Tell Don't Ask प्रोग्रामिंग की शैली में विशेष रूप से उपयोगी है।

अपने वर्ग सी के निम्न संस्करण पर विचार करें:

public class C { 
    public C(A a, B b, CListener L) { ... } 
    ... 
    public void foobar() { 
    String result = complexPrivateMethod(a, b); 
    L.fooBarred(result); 
    } 
} 

इस प्रकार, बल्कि सिर्फ परिणाम की गणना की तुलना में, आप परिणाम के बारे में कुछ इच्छुक पार्टी (जैसे एक यूजर इंटरफेस) को सूचित करें।

अब foobar परीक्षण करने के लिए, आप की पुष्टि है कि श्रोता सही ढंग से शुरू हो जाती है चाहते हैं:

public class CTest { 
    @Mock CListener mockListener; 
    ... 

    @Test itShouldTellCAboutFooBar() { 
     C c = new C(stubbedA, stubbedB, mockedListener); 
     ... 
     verify(mockedListener).fooBarred("foobar"); 
    } 
} 

verify का यह प्रयोग टेस्ट संचालित विकास के लिए विशिष्ट है: देखो फ्रीमैन & प्राइस के Growing Object-Oriented Software Guided by Tests

इस प्रकार, यदि आप मॉकिटो (प्रश्न) के पूर्ण संभावित का उपयोग करना चाहते हैं, तो आपको सबसे अधिक अपने कोड में संबंधित डिज़ाइन दर्शन को अपनाने की आवश्यकता है।

1

अब तक दिए गए उत्तरों अच्छे हैं, लेकिन अतिरिक्त सुविधाएं हैं जिनका आपने उल्लेख नहीं किया है। @Mock, @Spy, @InjectMocks एनोटेशन सभी बहुत उपयोगी हैं। verify(...) विधियों के साथ, विधि कॉल के आदेश को सत्यापित करने में सहायता के लिए इनऑर्डर क्लास भी है। और शायद आप पहले से ही matcher विधियों का उपयोग करें (<T> any(T t), anyString(), आदि), लेकिन आप यह नहीं दिखाते कि आप उन सुविधाओं का उपयोग करते हैं।

+0

निश्चित रूप से '@ मॉक' का उल्लेख करने लायक है - यह चीजों को कम और अधिक पठनीय बनाता है। तो आपकी टेस्ट क्लास की पहली पंक्ति 'निजी ए ए = मॉक (एक्लास) के बजाय '@ मॉक प्राइवेट ए' होगी;'। –