@RunWith (MockitoJUnitRunner.class) बनाम MockitoAnnotations.initMocks (यह)


118

एक नया jUnit4 परीक्षण लिखते समय, मैं सोच रहा हूं कि क्या @RunWith (MockitoJUnitRunner.class) या MockitoAnnotations.initMocks (यह) का उपयोग करना है

मैंने एक नया परीक्षण बनाया और विज़ार्ड ने स्वचालित रूप से धावक के साथ एक परीक्षण उत्पन्न किया। MockitoJUnitRunner के लिए Javadocs निम्नलिखित हैं:

4.4 के साथ संगत JUnit 4.4 और उच्चतर, यह धावक निम्नलिखित व्यवहार जोड़ता है:

Mock के साथ एनोटेट को आरंभिक रूप देता है, ताकि MockitoAnnotations.initMocks (ऑब्जेक्ट) का स्पष्ट उपयोग आवश्यक न हो। प्रत्येक परीक्षण विधि से पहले मोक्स को इनिशियलाइज़ किया जाता है। प्रत्येक परीक्षण विधि के बाद रूपरेखा उपयोग को मान्य करता है।

यह मेरे लिए स्पष्ट नहीं है कि रनर का उपयोग करने से initMocks () पद्धति का कोई फायदा हुआ है या नहीं

किसी भी विचार या लिंक की सराहना की जाएगी!

जवाबों:


147

MockitoJUnitRunnerआपको फ्रेमवर्क के उपयोग के साथ-साथ एक स्वत: सत्यापन प्रदान करता है initMocks()

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

  • आप स्थैतिक whenविधि को कॉल करते हैं , लेकिन मिलान के साथ स्टबिंग को पूरा नहीं करते हैं thenReturn, thenThrowया then(नीचे दिए गए कोड में त्रुटि 1)

  • आप verifyएक मॉक पर कॉल करते हैं, लेकिन विधि कॉल प्रदान करना भूल जाते हैं जिसे आप सत्यापित करने का प्रयास कर रहे हैं। (नीचे दिए गए कोड में त्रुटि 2)

  • आप whenविधि के बाद कॉल करते हैं doReturn, doThrowया doAnswerएक मॉक पास करते हैं, लेकिन उस विधि को प्रदान करना भूल जाते हैं जिसे आप स्टब करने की कोशिश कर रहे हैं। (नीचे दिए गए कोड में त्रुटि 3)

यदि आपके पास फ्रेमवर्क उपयोग की मान्यता नहीं है, तो निम्नलिखित गलतियों को मॉकिटो विधि के लिए कॉल करने तक सूचित नहीं किया जाता है। यह हो सकता है

  • उसी परीक्षण विधि में (जैसे त्रुटि 1 नीचे),
  • अगली परीक्षा विधि में (जैसे त्रुटि 2 नीचे),
  • अगली परीक्षा कक्षा में।

यदि वे अंतिम परीक्षण में होते हैं जो आप चलाते हैं (जैसे त्रुटि 3 नीचे), तो उन्हें रिपोर्ट नहीं किया जाएगा।

यहां बताया गया है कि प्रत्येक प्रकार की त्रुटियां कैसे दिख सकती हैं। यहां यह मान लें कि JUnit इन परीक्षणों को उस क्रम में चलाता है, जो वे यहां सूचीबद्ध हैं।

@Test
public void test1() {

    // ERROR 1
    // This compiles and runs, but it's an invalid use of the framework because 
    // Mockito is still waiting to find out what it should do when myMethod is called.
    // But Mockito can't report it yet, because the call to thenReturn might 
    // be yet to happen.
    when(myMock.method1());

    doSomeTestingStuff();

    // ERROR 1 is reported on the following line, even though it's not the line with
    // the error.
    verify(myMock).method2();

}

@Test
public void test2() {

    doSomeTestingStuff();

    // ERROR 2
    // This compiles and runs, but it's an invalid use of the framework because
    // Mockito doesn't know what method call to verify.  But Mockito can't report 
    // it yet, because the call to the method that's being verified might 
    // be yet to happen.
    verify(myMock);
}

@Test
public void test3() {

    // ERROR 2 is reported on the following line, even though it's not even in 
    // the same test as the error.
    doReturn("Hello").when(myMock).method1();


    // ERROR 3
    // This compiles and runs, but it's an invalid use of the framework because
    // Mockito doesn't know what method call is being stubbed.  But Mockito can't 
    // report it yet, because the call to the method that's being stubbed might 
    // be yet to happen.

    doReturn("World").when(myMock);

    doSomeTestingStuff(); 

    //  ERROR 3 is never reported, because there are no more Mockito calls. 
}

अब जब मैंने पहली बार पांच साल से अधिक समय पहले यह उत्तर लिखा था, तो मैंने लिखा था

तो मैं MockitoJUnitRunnerजहाँ भी संभव हो के उपयोग की सिफारिश करूँगा । हालाँकि, जैसा कि टॉमाज़ नर्कविक्ज़ ने सही ढंग से बताया है, यदि आप एक और JUnit धावक की जरूरत नहीं है, जैसे कि स्प्रिंग एक।

मेरी सिफारिश अब बदल गई है। मॉकिटो टीम ने एक नई सुविधा जोड़ी है क्योंकि मैंने पहली बार यह उत्तर लिखा था। यह एक JUnit नियम है, जो ठीक उसी प्रकार कार्य करता है जैसे कि MockitoJUnitRunner। लेकिन यह बेहतर है, क्योंकि यह अन्य धावकों के उपयोग को रोकता नहीं है।

शामिल

@Rule 
public MockitoRule rule = MockitoJUnit.rule();

आपकी परीक्षा कक्षा में यह मोक्स को इनिशियलाइज़ करता है, और फ्रेमवर्क सत्यापन को स्वचालित करता है; जैसा MockitoJUnitRunnerकरता है। लेकिन अब, आप SpringJUnit4ClassRunnerया किसी अन्य JUnitRunner का उपयोग कर सकते हैं । मॉकिटो 2.1.0 से, अतिरिक्त विकल्प हैं जो वास्तव में नियंत्रित करते हैं कि किस तरह की समस्याओं की सूचना मिलती है।


मैं निश्चित रूप से नहीं कह सकता कि वे समान हैं। एक परीक्षण के मामले में, जूनियर रनर सेटअप मेरे लिए विफल रहता है और जब तक मैं initMocks सेटअप नहीं करता है, तब तक मेरे मोक्स को ठीक से इंजेक्ट नहीं करता है
dtc

हम टेस्ट का उपयोग कर रहे हैं 6.8.8 + मॉकिटो 1.10.19 और, जाहिर है हम मॉकिटो जेनेटिटनर का उपयोग नहीं कर सकते हैं, लेकिन सत्यापन ढांचा अभी भी काम करता है! और यह बिल्कुल @David वालेस के रूप में काम करता है। क्या कोई समझा सकता है? क्या यह इसलिए है क्योंकि हमारे पास अभी भी @ पहले कॉलबैक और MockitoAnnotations.initMocks (यह) है?
युरोंस

@ yuranos87 कुछ ऐसा लगता है जो आपको एक नए प्रश्न के रूप में पूछना चाहिए। जब आप अपना कोड शामिल करना न भूलें - यदि आप कोड नहीं दिखाते हैं तो "यह कोड XYZ क्यों करता है" यह पूछना थोड़ा व्यर्थ है।
दाऊद इब्न करीम

1
TestRunner समाधान का उपयोग करके @ @
नियम

1
@alexandroid मेरा सबसे अच्छा सुझाव है कि आप अपना जवाब खुद लिखें @ExtendWith। यह वास्तव में कुछ ऐसा नहीं है जिसके बारे में मुझे पता है। स्टैक ओवरफ्लो के बारे में महान बात यह है कि इस तरह के एक सवाल पर, आप कई सही उत्तरों के साथ समाप्त कर सकते हैं।
दाऊद इब्न करीम

24

रनर का उपयोग करने से आप थोड़ी सी कोडिंग ( @Beforeविधि की कोई आवश्यकता नहीं ) बचा सकते हैं । दूसरी तरफ एक धावक का उपयोग करना कभी-कभी संभव नहीं होता है, अर्थात जब आप पहले से ही एक का उपयोग कर रहे हैं, जैसे SpringJUnit4ClassRunner

बस। यह सिर्फ वरीयता का मामला है।


2
InitMocks () लाइन के अलावा, किसी भी अन्य सेटअप के लिए @Before विधि की आवश्यकता होगी?
ओशनबेल्यू

2
@ ऑक्यूल्यू: यदि आपकी @Beforeपद्धति में कुछ भी शामिल है initMocks()तो आपको धावक को पलायन करने के बाद इसे संरक्षित करना होगा।
टॉमाज़ नर्कविक्ज़

डेविड वालेस के ढांचे के सत्यापन के बारे में मेरे सवाल का पूरी तरह से जवाब देता है इसलिए मैंने उस एक को स्वीकार कर लिया है, लेकिन यह इंगित करने के लिए +1 कि इस धावक को स्प्रिंग वन की तरह एक दूसरे के साथ इस्तेमाल नहीं किया जा सकता है। धन्यवाद!
ओशिनब्लयू

1
मैं स्प्रिंग बूट का उपयोग कर रहा हूं और मैं कह सकता हूं कि SpringJUnit4ClassRunnerस्वचालित रूप से मेरे लिए मोक्स को इनिशियलाइज़ करता है। मैं सादे वसंत के बारे में नहीं जानता, हालांकि।
गुस्तावोहेनके
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.