अद्यतन सितं, 2019: केवल मजाक ढांचे (डिफ़ॉल्ट रूप से) का समर्थन किया स्प्रिंग बूट से है Mockito । यदि आप स्प्रिंग का उपयोग करते हैं, तो उत्तर काफी स्पष्ट है।
मैं कहता हूं कि प्रतियोगिता JMockit और PowerMock के बीच है , फिर Mockito ।
मैं "सादे" jMock और EasyMock छोड़ दूंगा क्योंकि वे केवल प्रॉक्सी और CGLIB का उपयोग करते हैं और नए फ्रेमवर्क की तरह जावा 5 इंस्ट्रूमेंटेशन का उपयोग नहीं करते हैं।
jMock में भी 4 साल से अधिक की स्थिर रिलीज नहीं थी। jMock 2.6.0 को RC1 से RC2 पर जाने के लिए 2 साल की आवश्यकता थी, और फिर 2 साल पहले इसे वास्तव में रिलीज़ होने से पहले।
प्रॉक्सी और CGLIB बनाम इंस्ट्रूमेंटेशन के बारे में:
(ईज़ीमॉक और जेमॉक) java.lang.reflect.Proxy पर आधारित हैं, जिसे लागू करने के लिए एक इंटरफ़ेस की आवश्यकता होती है। इसके अतिरिक्त, वे CGLIB उपवर्ग पीढ़ी के माध्यम से कक्षाओं के लिए नकली वस्तुओं के निर्माण का समर्थन करते हैं। उस वजह से, कहा जाता है कि कक्षाएं अंतिम नहीं हो सकती हैं और केवल उदाहरण योग्य तरीकों का मजाक उड़ाया जा सकता है। सबसे महत्वपूर्ण बात, हालांकि, इन उपकरणों का उपयोग करते समय परीक्षण के तहत कोड की निर्भरता (अर्थात, अन्य वर्गों की वस्तुएं, जिन पर परीक्षण के तहत एक वर्ग निर्भर करता है) को परीक्षणों द्वारा नियंत्रित किया जाना चाहिए, ताकि ग्राहकों को नकली उदाहरण दिए जा सकें। उन निर्भरता के। इसलिए, निर्भरताएं केवल एक ग्राहक वर्ग में नए ऑपरेटर के साथ त्वरित नहीं की जा सकती हैं जिसके लिए हम यूनिट परीक्षण लिखना चाहते हैं।
अंततः, पारंपरिक मॉकिंग टूल्स की तकनीकी सीमाएँ उत्पादन कोड पर निम्नलिखित डिज़ाइन प्रतिबंध लगाती हैं:
- प्रत्येक वर्ग को एक परीक्षा में नकल करने की आवश्यकता हो सकती है या तो एक अलग इंटरफ़ेस लागू करना होगा या अंतिम नहीं होना चाहिए।
- परीक्षण किए जाने वाले प्रत्येक वर्ग की निर्भरता या तो कॉन्फ़िगर करने योग्य उदाहरण निर्माण विधियों (कारखानों या सेवा लोकेटर) के माध्यम से प्राप्त की जानी चाहिए, या निर्भरता इंजेक्शन के लिए उजागर की जानी चाहिए। अन्यथा, यूनिट परीक्षण परीक्षण के तहत यूनिट पर निर्भरता के नकली कार्यान्वयन को पारित करने में सक्षम नहीं होंगे।
- चूंकि केवल उदाहरण के तरीकों का मजाक उड़ाया जा सकता है, इसलिए परीक्षण की जाने वाली कक्षाएं उनकी निर्भरता पर किसी भी स्थिर तरीके को नहीं कह सकती हैं, न ही किसी भी निर्माणकर्ता का उपयोग करके उन्हें तुरंत भेज सकती हैं।
ऊपर http://jmockit.org/about.html से कॉपी किया गया है । इसके अलावा, यह अपने आप में (JMockit), पॉवरमॉक और मॉकिटो की तुलना कई तरीकों से करता है:
अब जावा के लिए अन्य मॉकिंग टूल हैं जो पारंपरिक लोगों की सीमाओं को पार करते हैं, उनके बीच पॉवरमॉक, jEasyTest और MockInject। जो JMockit के फीचर सेट के सबसे करीब आता है, वह है PowerMock, इसलिए मैं यहां इसका संक्षिप्त रूप से मूल्यांकन करूंगा (इसके अलावा, अन्य दो अधिक सीमित हैं और अब सक्रिय रूप से विकसित नहीं होते हैं)।
JMockit बनाम पॉवरमॉक
- सबसे पहले, पॉवरमॉक मॉकिंग के लिए एक पूर्ण एपीआई प्रदान नहीं करता है, बल्कि एक अन्य उपकरण के विस्तार के रूप में काम करता है, जो वर्तमान में ईज़ीमॉक या मॉकिटो हो सकता है। यह स्पष्ट रूप से उन उपकरणों के मौजूदा उपयोगकर्ताओं के लिए एक फायदा है।
- दूसरी ओर, JMockit, पूरी तरह से नए API प्रदान करता है, हालाँकि इसका मुख्य API (Expectations) EasyMock और jMock दोनों के समान है। हालांकि यह एक लंबा सीखने की अवस्था बनाता है, यह JMockit को एपीआई का उपयोग करने के लिए एक सरल, अधिक सुसंगत और आसान प्रदान करने की अनुमति देता है।
- JMockit Expectations API की तुलना में, PowerMock API अधिक "निम्न-स्तर" है, जो उपयोगकर्ताओं को यह पता लगाने के लिए मजबूर करता है और निर्दिष्ट करता है कि परीक्षण के लिए कौन सी कक्षाओं को तैयार करने की आवश्यकता है (@PrepareForTest ({ClassA .class, ...}) एनोटेशन के साथ ) और विभिन्न प्रकार के भाषा निर्माणों से निपटने के लिए विशिष्ट API कॉल की आवश्यकता होती है जो उत्पादन कोड में मौजूद हो सकते हैं: स्थैतिक विधियाँ (mockStatic (ClassA.class)), निर्माणकर्ता (दमनक (निर्माणकर्ता (ClassXyz.class))), निर्माण आह्वान ( अपेक्षानुरूप (AClass.class)), आंशिक मोक्स (createPartialMock (ClassX.class, "methodToMock")), आदि।
- JMockit अपेक्षाओं के साथ, सभी प्रकार के तरीकों और निर्माणकर्ताओं का विशुद्ध रूप से घोषित तरीके से मजाक उड़ाया जाता है, @Mocked एनोटेशन में नियमित अभिव्यक्तियों के माध्यम से या केवल रिकॉर्ड किए गए अपेक्षाओं वाले सदस्यों को "अन-मॉकिंग" करके आंशिक रूप से निर्दिष्ट किया जाता है; यही है, डेवलपर बस परीक्षण के वर्ग के लिए कुछ साझा "नकली क्षेत्र", या कुछ "स्थानीय नकली क्षेत्र" और / या व्यक्तिगत परीक्षण विधियों के लिए "नकली पैरामीटर" की घोषणा करता है (और इस अंतिम मामले में @ अक्सर टिप्पणी नहीं करेगा जरूरत हो)।
- JMockit में उपलब्ध कुछ क्षमताएं, जैसे कि समतुल्यता और हैशकोड के लिए समर्थन, ओवरराइड की गई विधियाँ और अन्य, वर्तमान में PowerMock में समर्थित नहीं हैं। इसके अलावा, परीक्षण के क्रियान्वयन के बिना JMockit की क्षमता और निर्दिष्ट आधार प्रकार के नकली कार्यान्वयन को पकड़ने के लिए कोई समान नहीं है, परीक्षण कोड के बिना ही वास्तविक कार्यान्वयन कक्षाओं का कोई भी ज्ञान नहीं है।
- मॉक क्लास के संशोधित संस्करण उत्पन्न करने के लिए पॉवरमॉक कस्टम क्लास लोडर (आमतौर पर एक प्रति परीक्षण वर्ग) का उपयोग करता है। कस्टम क्लास लोडर के ऐसे भारी उपयोग से तीसरे पक्ष के पुस्तकालयों के साथ संघर्ष हो सकता है, इसलिए कभी-कभी परीक्षण कक्षाओं पर @PowerMockIgnore ("package.to.be.ignored") एनोटेशन का उपयोग करने की आवश्यकता होती है।
- JMockit (एक "जावा एजेंट" के माध्यम से रनटाइम इंस्ट्रूमेंटेशन) द्वारा उपयोग किया जाने वाला तंत्र सरल और सुरक्षित है, हालांकि JDK 1.5 पर विकसित होने पर इसे JVM को "-javaagent" पैरामीटर पास करने की आवश्यकता होती है; JDK 1.6+ पर (जिसका उपयोग हमेशा विकास के लिए किया जा सकता है, भले ही पुराने संस्करण पर तैनात किया गया हो) ऐसी कोई आवश्यकता नहीं है, क्योंकि JMockit पारदर्शी तरीके से अटैच एपीआई का उपयोग करके जावा एजेंट को मांग पर लोड कर सकता है।
एक और हालिया नकली उपकरण मॉकिटो है। यद्यपि यह पुराने टूल (jMock, EasyMock) की सीमाओं को पार करने का प्रयास नहीं करता है, यह मॉक के साथ व्यवहार परीक्षण की एक नई शैली पेश करता है। JMockit सत्यापन विकल्प API के माध्यम से इस वैकल्पिक शैली का भी समर्थन करता है।
JMockit बनाम मॉकिटो
- मॉकिटो रिकॉर्ड करने के लिए (जब (...)) और सत्यापित (सत्यापन (...)) चरणों के बीच अलग कोड बनाने के लिए अपने एपीआई पर स्पष्ट कॉल पर निर्भर करता है। इसका मतलब यह है कि परीक्षण कोड में एक नकली वस्तु के लिए किसी भी आह्वान को मॉकिंग एपीआई के लिए एक कॉल की आवश्यकता होगी। इसके अतिरिक्त, यह अक्सर (...) और सत्यापन (मॉक) ... कॉल को दोहराए जाने की ओर ले जाएगा।
- JMockit के साथ, कोई समान कॉल मौजूद नहीं है। निश्चित रूप से, हमारे पास नए NonStrictExpectations () और नए Verifications () निर्माता कॉल हैं, लेकिन वे केवल एक बार परीक्षण (आमतौर पर) के अनुसार होते हैं, और इनवोकेशन से नकली तरीकों और निर्माणकर्ताओं से पूरी तरह से अलग होते हैं।
- मॉकिटो एपीआई में कई असंगतताएं होती हैं, जो कि नकली तरीकों के लिए उपयोग किए गए सिंटैक्स में असंगतता होती हैं। रिकॉर्ड चरण में, हमारे पास जब (mock.mockedMethod (args)) जैसे कॉल होते हैं ... जबकि सत्यापन चरण में इस कॉल को वेरिफ़ाइड (mock) .mockedMethod (args) लिखा जाएगा। ध्यान दें कि पहले मामले में mockedMethod पर मंगलाचरण सीधे मॉक ऑब्जेक्ट पर किया जाता है, जबकि दूसरे मामले में यह सत्यापन (मॉक) द्वारा लौटाए गए ऑब्जेक्ट पर बनाया जाता है।
- JMockit में ऐसी कोई असंगतता नहीं है क्योंकि नकली तरीकों के लिए आक्रमण हमेशा सीधे नकली उदाहरणों पर किए जाते हैं। (केवल एक अपवाद के साथ: एक ही नकली उदाहरण पर इनवोकेशन से मिलान करने के लिए, एक onInstance (मॉक) कॉल का उपयोग किया जाता है, जिसके परिणामस्वरूप onInstance (mock) .mockedMethod (args) जैसे कोड होते हैं; अधिकांश परीक्षणों के लिए इसका उपयोग करने की आवश्यकता नहीं होगी, हालाँकि )
- अन्य मॉकिंग टूल की तरह, जो विधि को अस्तर / रैपिंग पर निर्भर करते हैं, मॉकिटो भी शून्य तरीकों को ठोकर देने पर असंगत सिंटैक्स में चलता है। उदाहरण के लिए, आप तब लिखते हैं जब (mockedList.get (1))। तब (नया RuntimeException ()); एक गैर-शून्य विधि के लिए, और doThrow (नई RuntimeException ())। जब (mockList) .clear (); एक शून्य के लिए। JMockit के साथ, यह हमेशा एक ही वाक्यविन्यास है: mockedList.clear (); परिणाम = नया RuntimeException () ;;
- फिर भी मॉकिटो जासूसों के उपयोग में एक और असंगतता उत्पन्न होती है: "मोक्स" जो वास्तविक तरीकों को जासूसी उदाहरण पर निष्पादित करने की अनुमति देता है। उदाहरण के लिए, यदि जासूस एक खाली सूची को संदर्भित करता है, तो लिखने के बजाय जब (spy.get (0))। तब। पुनर्जन्म ("फू") आपको doReturn ("फू") लिखना होगा। जब (जासूस) .get 0)। JMockit के साथ, डायनेमिक मॉकिंग फीचर जासूसों को समान कार्यक्षमता प्रदान करता है, लेकिन इस मुद्दे के बिना वास्तविक तरीकों से केवल रिप्ले चरण के दौरान निष्पादित किया जाता है।
- EasyMock और jMock में, जावा के लिए पहला मॉकिंग एपीआई, ध्यान पूरी तरह से नकली तरीकों के अपेक्षित इनवॉइस की रिकॉर्डिंग पर था, मॉक ऑब्जेक्ट के लिए (डिफ़ॉल्ट रूप से) अनपेक्षित इनवोकेशन की अनुमति नहीं देता है। वे API मॉक ऑब्जेक्ट के लिए अनुमत इनवोकेशन की रिकॉर्डिंग भी प्रदान करते हैं जो अनपेक्षित इनवोकेशन की अनुमति देते हैं, लेकिन इसे द्वितीय श्रेणी की सुविधा के रूप में माना जाता था। इसके अतिरिक्त, इन उपकरणों के साथ परीक्षण के तहत कोड का उपयोग करने के बाद नकली करने के लिए स्पष्ट रूप से चालान को सत्यापित करने का कोई तरीका नहीं है। इस तरह के सभी सत्यापन निहित और स्वचालित रूप से किए जाते हैं।
- मॉकिटो (और यूनिट्स मॉक में भी), विपरीत दृष्टिकोण लिया जाता है। परीक्षण के दौरान हो सकने वाली वस्तुओं के नकली होने के सभी आह्वान, चाहे दर्ज हो या न हो, की अनुमति नहीं है। परीक्षण के तहत कोड का उपयोग करने के बाद सत्यापन स्पष्ट रूप से किया जाता है, कभी भी स्वचालित रूप से नहीं।
- दोनों दृष्टिकोण बहुत चरम हैं, और परिणामस्वरूप इष्टतम से कम है। JMockit Expectations & Verifications एकमात्र API है जो डेवलपर को प्रत्येक परीक्षण के लिए सख्त (डिफ़ॉल्ट रूप से अपेक्षित) और गैर-सख्त (डिफ़ॉल्ट रूप से अनुमत) नकली चालान का सर्वश्रेष्ठ संयोजन चुनने की अनुमति देता है।
- अधिक स्पष्ट होने के लिए, मॉकिटो एपीआई में निम्नलिखित कमी है। यदि आपको यह सत्यापित करने की आवश्यकता है कि परीक्षण के दौरान एक गैर-शून्य मॉकडाउन विधि के लिए एक आह्वान हुआ था, लेकिन परीक्षण के लिए उस विधि से वापसी मूल्य की आवश्यकता होती है जो कि वापसी प्रकार के लिए डिफ़ॉल्ट से अलग है, तो मॉकिटो परीक्षण में डुप्लिकेट कोड होगा: a (mock.someMethod ())। तब रिकॉर्ड में चरण (xyz) कॉल करें और सत्यापित चरण में एक सत्यापित (mock) .someMethod () करें। JMockit के साथ, एक सख्त उम्मीद हमेशा दर्ज की जा सकती है, जिसे स्पष्ट रूप से सत्यापित नहीं करना होगा। वैकल्पिक रूप से, एक आहरण गणना बाधा (समय = 1) को किसी भी रिकॉर्ड की गई गैर-सख्त अपेक्षा के लिए निर्दिष्ट किया जा सकता है (मॉकिटो के रूप में ऐसी बाधाएं केवल एक सत्यापित (नकली, बाधा) कॉल में निर्दिष्ट की जा सकती हैं)।
- आदेश में सत्यापन के लिए मॉकिटो के खराब सिंटैक्स हैं, और पूर्ण सत्यापन के लिए (जो कि, यह जांचना कि सभी वस्तुओं को नकली करने के लिए स्पष्ट रूप से सत्यापित किया गया है)। पहले मामले में, एक अतिरिक्त ऑब्जेक्ट बनाने की आवश्यकता है, और उस पर किए गए सत्यापन को कॉल करता है: InOrder inOrder = inOrder (mock1, mock2, ...)। दूसरे मामले में, VerNoMoreInteractions (mock) या verifyZeroInteractions (mock1, mock2) जैसे कॉल किए जाने की आवश्यकता है।
- JMockit के साथ, आप बस नए VerificationsInOrder () या नए FullVerifications () के बजाय नए Verifications () (या नए FullVerificationsInOrder () दोनों आवश्यकताओं को संयोजित करने के लिए) लिखते हैं। यह निर्दिष्ट करने की आवश्यकता नहीं है कि कौन सी नकली वस्तुएं शामिल हैं। कोई अतिरिक्त मजाक नहीं एपीआई कॉल। और एक बोनस के रूप में, एक सत्यापित सत्यापन ब्लॉक के अंदर unverifiedInvocations () कॉल करके, आप ऑर्डर से संबंधित सत्यापन कर सकते हैं जो केवल मॉकिटो में असंभव हैं।
अंत में, JMockit टेस्टिंग टूलकिट का व्यापक दायरा और है एक संपूर्ण और परिष्कृत डेवलपर परीक्षण समाधान प्रदान करने के लिए अन्य तुलना में अधिक महत्वाकांक्षी लक्ष्य हैं। कृत्रिम सीमाओं के बिना भी मॉकिंग के लिए एक अच्छा एपीआई परीक्षण के उत्पादक निर्माण के लिए पर्याप्त नहीं है। एक IDE-agnostic, प्रयोग करने में आसान, और अच्छी तरह से एकीकृत कोड कवरेज उपकरण भी आवश्यक है, और यही JMockit कवरेज प्रदान करना है। डेवलपर परीक्षण टूलसेट का एक और टुकड़ा जो अधिक उपयोगी हो जाएगा क्योंकि परीक्षण सूट आकार में बढ़ता है, उत्पादन कोड में स्थानीय परिवर्तन के बाद वृद्धिशील परीक्षण करने की क्षमता है; यह भी कवरेज उपकरण में शामिल है।
(दी गई, स्रोत पक्षपाती हो सकता है, लेकिन अच्छी तरह से ...)
मैं कहता हूं कि JMockit के साथ जाना चाहिए । जब आप परीक्षण किए जाने वाले वर्ग को नियंत्रित नहीं कर सकते (या आप अनुकूलता के कारण इसे तोड़ नहीं सकते हैं)
JMockit के साथ मेरे अनुभव बहुत सकारात्मक रहे हैं।