Mockito - doReturn के बीच अंतर () और कब ()


197

मैं वर्तमान में स्प्रिंग एमवीसी एप्लिकेशन में अपनी सेवा स्तर की वस्तुओं को मॉक करने के लिए मॉकिटो का उपयोग करने की प्रक्रिया में हूं जिसमें मैं अपने नियंत्रक तरीकों का परीक्षण करना चाहता हूं। हालांकि, जैसा कि मैं मॉकिटो की बारीकियों पर पढ़ रहा हूं, मैंने पाया है कि विधियां doReturn(...).when(...)इसके बराबर हैं when(...).thenReturn(...)। तो, मेरे सवाल का क्या दो तरीकों कि एक ही बात करते हैं या क्या दोनों के बीच सूक्ष्म अंतर नहीं है होने की बात है doReturn(...).when(...)और when(...).thenReturn(...)?

किसी भी सहायता की सराहना की जाएगी।


1
Javadoc में कुछ मामले होते हैं जहाँ doReturn()उपयोगी है।
सॉटिरिओस डेलिमोनोलिस

5
मुझे लगता है कि मुख्य अंतर में से एक doReturn (...) है। जब (..) एक पुराना है और इसका प्रकार सुरक्षित नहीं है और इसलिए हम इसे कभी-कभी उपयोग कर सकते हैं जब कंपाइलर कास्टिंग के बारे में शिकायत करता रहता है। जब (..)। तब पुनर्जन्म (..) प्रकार की सुरक्षा के लिहाज से बेहतर है
user2511882

जवाबों:


228

स्टबिंग के लिए दो वाक्यविन्यास लगभग बराबर हैं। हालांकि, आप हमेशाdoReturn/when स्टबिंग के लिए उपयोग कर सकते हैं ; लेकिन ऐसे मामलों में जहां आप देखते हैं नहीं कर सकते का उपयोग when/thenReturn। स्टबिंग शून्य विधियाँ एक ऐसी है। दूसरों में मॉकिटो जासूसों के साथ उपयोग शामिल है, और एक ही विधि को एक से अधिक बार ठोकर मारना।

एक चीज जो when/thenReturnआपको देती है, वह हैdoReturn/when है मान की टाइप-चेकिंग जो आप वापस कर रहे हैं, संकलन समय पर। हालाँकि, मेरा मानना ​​है कि यह लगभग कोई मूल्य नहीं है - यदि आपको टाइप गलत हुआ है, तो आप अपना परीक्षण चलाते ही पता लगा लेंगे।

मैं दृढ़ता से केवल उपयोग करने की सलाह देता हूं doReturn/when। जब कोई करेगा तो दो वाक्यविन्यास सीखने का कोई मतलब नहीं है।

आप मॉकिटो "व्याकरण" बनाने में मेरे जवाब का उल्लेख करना चाह सकते हैं - एक बहुत ही बारीकी से संबंधित प्रश्न का अधिक विस्तृत जवाब।


16
मैं डेविड से असहमत हूं। मैं अक्सर उन स्थितियों में भाग लेता हूं जहां मैं गलत प्रकार को वापस करता हूं जब उपयोग doReturn/whenकरते हैं और अगले कुछ मिनट बिताते हैं जो पता चलता है कि क्या गलत हुआ। कंपाइल टाइप टाइप चेकिंग के साथ बेहद उपयोगी हो जाता है when/thenReturn
साकेत

11
बस इस बात का ध्यान रखें कि मॉकिटो आपको सलाह देता है कि आप when/thenReturnइसके बजाय इसका उपयोग करें doReturn/when
कोडिएन्जेल

2
@CodyEngel और वहाँ इस तरह के एक सिफारिश के लिए कोई कारण नहीं है, मैं क्या अपने जवाब यहाँ और पर में रेखांकित किया है के अलावा अन्य है stackoverflow.com/q/11462697 । कई साल पहले, मैंने ब्राइस दुथिल के साथ इस पर चर्चा की, जो वर्तमान में मॉकिटो के मुख्य डेवलपर के रूप में काम कर रहे हैं, और मेरी सबसे अच्छी स्मृति के लिए, वह सहमत हैं। मैं उसे यहाँ एक टिप्पणी पोस्ट करने के लिए कहूँगा (कोई गारंटी नहीं कि वह ऐसा करेगा)।
दाऊद इब्न करीम

18
जावाडोक कहा गया है कि doReturn/whenएक व्यापार बंद है। टीम एक तरह से या किसी अन्य की सिफारिश नहीं करती है, लेकिन ध्यान दें कि when/thenदृष्टिकोण अधिक सहज, अधिक पठनीय है और संकलन समय की जांच की पेशकश करता है, यह वह दृष्टिकोण है जिसने मॉकिटो को लोकप्रिय और उपयोग करने में आसान बना दिया है, यह मत भूलो कि कोड आधार कब साझा किया जाता है आपकी टीम में विभिन्न कौशल; अभी तक इसमें जासूसों और शून्य तरीकों के बारे में कमियां हैं।
ब्राइस

5
सिर्फ रिकॉर्ड के लिए: विधि कॉल की योदा शैली कोडिंग में बदलने doReturn()का बड़ा नुकसान है। बाद में जो चीज सबसे पहले लिखी जाती है, वह है। ज्यादातर लोग बाएं से दाएं पढ़ते हैं; इसलिए अब आपको अपने सिर में रिटर्न-जब लॉजिक को उलटने के लिए लगातार याद रखना होगा।
भूतकाल

199

यदि आप एक जासूसी वस्तु का उपयोग करते हैं तो अलग तरीके से व्यवहार करते हैं (मटके के साथ @Spyएनोटेट @Mock):

  • when(...) thenReturn(...) निर्दिष्ट मूल्य वापस होने से ठीक पहले एक वास्तविक विधि कॉल करता है। इसलिए यदि इस विधि को एक अपवाद कहा जाता है, तो आपको इससे निपटना होगा / इसका मज़ाक करना होगा / निश्चित रूप से आपको अभी भी अपना परिणाम मिलेगा (जो आपको परिभाषित करता है thenReturn(...))

  • doReturn(...) when(...) विधि बिलकुल नहीं कहता

उदाहरण:

public class MyClass {
     protected String methodToBeTested() {
           return anotherMethodInClass();
     }

     protected String anotherMethodInClass() {
          throw new NullPointerException();
     }
}

परीक्षा:

@Spy
private MyClass myClass;

// ...

// would work fine
doReturn("test").when(myClass).anotherMethodInClass();

// would throw a NullPointerException
when(myClass.anotherMethodInClass()).thenReturn("test");

37
यह व्यवहार सिर्फ जासूसी वस्तुओं के लिए काम करता है, क्योंकि वास्तविक वस्तुओं के "आवरण" हैं। मॉक किए गए ऑब्जेक्ट के मामले में, इससे कोई फर्क नहीं पड़ता कि यह कब / फिर है। नकली वस्तुएं वास्तविक तरीकों को कभी नहीं बुलाती हैं।
राफेल ऑरगियो

क्या आप कृपया अधिक जानकारी दे सकते हैं कि हमें इस कार्यक्षमता का उपयोग करने की आवश्यकता क्यों है? मुझे व्यावहारिक उपयोग का मामला नहीं दिख रहा है। परीक्षण का इरादा विभिन्न उपयोग मामलों के तहत कोड की शुद्धता की पुष्टि करता है। यदि विधि का
कॉल्स

@Gleichmut यह एक काल्पनिक परिदृश्य था, जहाँ मैं doReturn का उपयोग / लाभ दिखाता हूँ। एक वास्तविक अनुप्रयोग में, एक विधि जो केवल एक अपवाद को वापस
लेती है वह

1
स्पष्टीकरण के लिए बस: जब ()। फिर रीटर्न () - विधि वास्तविक विधि कहती है (एक जासूस की - मक्स के लिए कोई फर्क नहीं पड़ता) केवल एक बार। यह उस पंक्ति में होता है जिसे आप नकली व्यवहार निर्दिष्ट करते हैं (जब ( myClass.anotherMethodInClass () .thenRet ...)। उसके बाद वास्तविक विधि को फिर कभी नहीं बुलाया जाता है। शायद यह जानने के लिए अच्छा हो कि आपने स्पष्टीकरण पढ़ते समय कुछ सजावटी तर्क की अपेक्षा की थी। ऊपर।
जोनास

यह एक फायदा नहीं लगता है doReturn(), यह पुस्तकालय के दुरुपयोग की तरह दिखता है। शुद्ध मॉकिंग के बजाय जासूसी करने का उद्देश्य वास्तविक कॉल का लाभ उठाना है। वे इस तरह जासूसों का उपयोग करने के खिलाफ चेतावनी देते हैं: github.com/mockito/mockito/wiki/Using-Spies-(and-Fakes) (और वर्ग को बढ़ाने और इसके बजाय विधि को ओवरराइड करने की सलाह देते हैं)
मैथ्यू

13

Mockito जावाडोक क्यों उपयोग बताने के लिए लगता है doReturn()के बजाय when() आप Mockito.when (वस्तु) का उपयोग नहीं कर सकते हैं जब उन दुर्लभ अवसरों में उपयोग doReturn ()।

सावधान रहें कि Mockito.when (ऑब्जेक्ट) को हमेशा स्टबिंग के लिए अनुशंसित किया जाता है क्योंकि यह तर्क प्रकार-सुरक्षित और अधिक पठनीय है (विशेषकर जब लगातार कॉल को ठोकर मारता है)।

यहां उन दुर्लभ मौकों को दिखाया गया है जब doReturn () काम आता है:

1. जब वास्तविक वस्तुओं की जासूसी और जासूसी पर वास्तविक तरीकों को कॉल करने से दुष्प्रभाव होता है

List list = new LinkedList(); List spy = spy(list);

// असंभव: वास्तविक विधि को स्पाईगेट कहा जाता है। (0) फेंकता है IndexOutOfBoundsException (सूची अभी तक उपलब्ध नहीं है)

when(spy.get(0)).thenReturn("foo");

// आपको स्टबिंग के लिए doReturn () का उपयोग करना होगा: doReturn("foo").when(spy).get(0);

2. पिछले अपवाद-स्टबिंग को ओवरराइड करना:

when(mock.foo()).thenThrow(new RuntimeException());

// असंभव: अपवाद-रुका हुआ फू () विधि कहा जाता है इसलिए RuntimeException को फेंक दिया जाता है। when(mock.foo()).thenReturn("bar");

// आपको स्टबिंग के लिए doReturn () का उपयोग करना होगा:

doReturn("bar").when(mock).foo(); उपरोक्त परिदृश्य मॉकिटो के सुरुचिपूर्ण सिंटैक्स का एक ट्रेडऑफ़ दिखाता है। ध्यान दें कि परिदृश्य बहुत दुर्लभ हैं, हालांकि। जासूसी छिटपुट होनी चाहिए और अपवाद-अतिव्याप्ति बहुत दुर्लभ है। यह उल्लेख नहीं है कि सामान्य रूप से ओवरराइडिंग स्टबिंग एक संभावित कोड गंध है जो बहुत अधिक स्टबिंग को इंगित करता है।


6

इस उत्तर को जारी रखते हुए , एक और अंतर है कि यदि आप चाहते हैं कि आपका तरीका उदाहरण के लिए अलग-अलग मान लौटाए, जब पहली बार कॉल किया जाता है, दूसरी बार कॉल किया जाता है आदि तो आप उदाहरण के लिए मान को पास कर सकते हैं ...

PowerMockito.doReturn(false, false, true).when(SomeClass.class, "SomeMethod", Matchers.any(SomeClass.class));

अतः यह झूठे वापस आ जाएगा जब विधि को उसी परीक्षण मामले में बुलाया जाएगा और फिर यह फिर से गलत और अंतिम रूप से सही लौटेगा।


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