एक नकली और ठूंठ के बीच अंतर क्या है?


961

मैंने परीक्षण में मॉकिंग बनाम स्टबिंग के बारे में विभिन्न लेख पढ़े हैं, जिनमें मार्टिन फाउलर की मोक्स स्टब्स नहीं हैं , लेकिन फिर भी यह अंतर समझ में नहीं आता है।



75
@OP क्योंकि कोई अंतर नहीं है। यह लेख, समुदाय द्वारा जितना प्यार किया गया है, वह है - पूरे सम्मान के साथ - ऐसे शब्दों में अतिरिक्त अर्थ जोड़कर सब कुछ अनावश्यक रूप से भ्रमित कर देना जो अन्यथा समझने में आसान होते हैं और चीजों को अनावश्यक रूप से जटिल बनाते हैं। नकली सिर्फ एक मजाक है, कुछ ऐसा जो असली के बजाय नकली व्यापार तर्क देता है। अंत में व्यवहार के लिए जाँच करना आपकी पसंद है, लेकिन यह अभी भी एक नकली है। या जो भी आप इसे कॉल करना चाहते हैं, लेकिन इसे एक बनाएं। एक बाल को विभाजित न करें। इसे सरल रखें, ताकि लोग आपकी अवधारणा को आसानी से समझ सकें - जो उपरोक्त लेख के साथ विफल होता है।
WST

10
"मॉक, फेक और स्टब्स के बीच का वर्गीकरण साहित्य में अत्यधिक असंगत है।" कई उद्धरणों के साथ। अभी भी मेरे पसंदीदा विकिपीडिया उद्धरणों में से एक है - अगर ऐसा कुछ मौजूद है :) en.wikipedia.org/wiki/Mock_object
JD।

11
मार्टिन फाउलर का लेख शुरुआती लोगों के लिए समझना बहुत मुश्किल है।
lmiguelvargasf 15

1
जिस तरह से मैं यह समझता हूं कि डब डेटा के संग्रह की तरह एक स्टब सिर्फ आपके परीक्षण के लिए एक फेंक वस्तु होगी। एक मॉक कुछ और जटिल का एक चतुराई से अतिरंजित संस्करण होगा, विभिन्न तरीकों के साथ एक सेवा परत की तरह, जिसे आपने अपने परीक्षणों के लिए, व्यवहार को बदल दिया होगा। दो चीजों का एक साथ उपयोग किया जाता है, जैसे कि आप कुछ ठूंसी वस्तुओं को अपनी नकली परत में पास कर सकते हैं।
JsonStatham

जवाबों:


745

ठूंठ

मेरा मानना ​​है कि सबसे बड़ा अंतर यह है कि एक स्टब जिसे आप पहले से ही निर्धारित व्यवहार के साथ लिख चुके हैं। इसलिए आपके पास एक ऐसा वर्ग होगा जो परीक्षण उद्देश्यों के लिए निर्भरता (अमूर्त वर्ग या इंटरफ़ेस की सबसे अधिक संभावना है) को लागू करता है और तरीकों को केवल निर्धारित प्रतिक्रियाओं के साथ बाहर रखा जाएगा। वे कुछ भी कल्पना नहीं करेंगे और आपने अपने परीक्षण के बाहर इसके लिए पहले से ही स्टब कोड लिखा होगा।

दिखावटी

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

मोक्स और स्टब्स के बीच अंतर

मॉक के साथ लिखे initialize -> set expectations -> exercise -> verifyगए परीक्षण आमतौर पर परीक्षण के लिए एक पैटर्न का पालन करते हैं । जबकि पूर्व-लिखित ठूंठ का अनुसरण किया जाएगा initialize -> exercise -> verify

मोक्स और स्टब्स के बीच समानता

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


875

प्रस्तावना

वस्तुओं की कई परिभाषाएँ हैं, जो वास्तविक नहीं हैं। सामान्य शब्द टेस्ट डबल है । इस शब्द में शामिल हैं: डमी , नकली , ठूंठ , नकली

संदर्भ

मार्टिन फाउलर के लेख के अनुसार :

  • डमी वस्तुओं को पास किया जाता है लेकिन वास्तव में कभी भी उपयोग नहीं किया जाता है। आमतौर पर वे बस पैरामीटर सूचियों को भरने के लिए उपयोग किए जाते हैं।
  • नकली वस्तुओं में वास्तव में काम करने वाले कार्यान्वयन होते हैं, लेकिन आमतौर पर कुछ शॉर्टकट लेते हैं जो उन्हें उत्पादन के लिए उपयुक्त नहीं बनाता है (स्मृति डेटाबेस में एक अच्छा उदाहरण है)।
  • स्टब्स परीक्षण के दौरान किए गए कॉलों के लिए डिब्बाबंद उत्तर प्रदान करते हैं, आमतौर पर परीक्षण के लिए प्रोग्राम किए गए बाहर के किसी भी चीज़ का जवाब नहीं देते हैं। स्टब्स कॉल के बारे में जानकारी भी रिकॉर्ड कर सकते हैं, जैसे कि एक ईमेल गेटवे स्टब जो इसे भेजे गए संदेशों को याद रखता है, या हो सकता है कि यह केवल कितने संदेश 'भेजे'।
  • मोक्स वे हैं जिनके बारे में हम यहां बात कर रहे हैं: ऑब्जेक्ट्स पूर्व-अपेक्षाओं के साथ प्रोग्राम किए जाते हैं जो उन कॉलों का एक विनिर्देश बनाते हैं जो उन्हें प्राप्त होने की उम्मीद है।

अंदाज

मोक्स बनाम स्टब्स = व्यवहार परीक्षण बनाम राज्य परीक्षण

सिद्धांत

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

जीवन चक्र

स्टब्स के साथ परीक्षण जीवन चक्र:

  1. सेटअप - वह वस्तु तैयार करें जिसका परीक्षण किया जा रहा है और उसके स्टब्स सहयोगी।
  2. व्यायाम - कार्यक्षमता का परीक्षण करें।
  3. सत्यापित करें स्थिति - ऑब्जेक्ट की स्थिति की जांच करने के लिए जोर का प्रयोग करें।
  4. टियरडाउन - संसाधनों को साफ करना।

मोक्स के साथ जीवन चक्र का परीक्षण करें:

  1. सेटअप डेटा - वह ऑब्जेक्ट तैयार करें जिसका परीक्षण किया जा रहा है।
  2. सेटअप अपेक्षाएँ - प्राथमिक ऑब्जेक्ट द्वारा उपयोग किए जा रहे मॉक में अपेक्षाएँ तैयार करें।
  3. व्यायाम - कार्यक्षमता का परीक्षण करें।
  4. उम्मीदों को सत्यापित करें - सत्यापित करें कि सही तरीकों को नकली में लागू किया गया है।
  5. सत्यापित करें स्थिति - ऑब्जेक्ट की स्थिति की जांच करने के लिए जोर का प्रयोग करें।
  6. टियरडाउन - संसाधनों को साफ करना।

सारांश

दोनों मोज़ेक और स्टब्स परीक्षण प्रश्न का उत्तर देते हैं: परिणाम क्या है?

मोक्स के साथ परीक्षण में भी रुचि है: परिणाम कैसे प्राप्त किया गया है?


रुको, नकली भी डिब्बाबंद जवाब वापस? कारण अन्यथा वे प्रश्न का उत्तर क्यों देते हैं?
AturSams

आपने जो लिखा उससे मैं बता सकता हूं कि मोक्स = स्टब्स + अपेक्षाएं और सत्यापन, क्योंकि मॉक "परीक्षण के दौरान किए गए कॉल्स के लिए उत्तर प्रदान करता है, आमतौर पर टेस्ट के लिए जो भी प्रोग्राम किया जाता है, उसके बाहर किसी भी चीज का जवाब नहीं दिया जाता है" (स्टब्स के समान)। और फाउलर ने एक स्टब के उदाहरण के रूप में दिखाया कि वास्तव में एक जासूस का उदाहरण है! इसका मतलब है कि एक नकली एक ठूंठ है, और एक जासूस एक ठूंठ है। और एक स्टब सिर्फ एक वस्तु है जिसमें कई काम करने के तरीके हैं। यह भी बताता है कि मॉकिटो ने स्टब () विधि को क्यों चित्रित किया।
kolobok

मुझे यह भ्रामक लगता है और स्वीकृत उत्तर यह "उम्मीद की स्थापना" है, इसका क्या मतलब है? आमतौर पर, "मुख्य कोड" में आप वे परिणाम बनाते हैं जिनकी आपको अपेक्षा होती है। ऐसा लगता है कि आप उम्मीदों को किसी तरह नकली वस्तु में डाल देते हैं, हालांकि, जो मुझे समझ में नहीं आता है। इसके अलावा, आप आसानी से कुछ इनपुट के साथ आसानी से मॉक एक्सरसाइज कर सकते हैं, परिणाम स्टोर कर सकते हैं, बाद में "उम्मीदें" बना सकते हैं और फिर तुलना कर सकते हैं। आप शब्दावली का उपयोग करते हैं जो मुझे बहुत सार और अस्पष्ट लगता है।
आइसफेयर

364

एक ठूंठ एक साधारण नकली वस्तु है। यह सिर्फ सुनिश्चित करता है कि परीक्षण सुचारू रूप से चलता रहे।
एक नकली एक चालाक ठूंठ है। आप अपने परीक्षण पास से सत्यापित करते हैं।


33
मुझे लगता है कि यह उत्तर पर सबसे रसीला और हाजिर है। Takeaway: एक नकली IS-A ठूंठ। stackoverflow.com/a/17810004/2288628 इस उत्तर का लंबा संस्करण है।
PoweredByRice

8
मुझे नहीं लगता कि एक मजाक एक ठूंठ है। मोक्स का उपयोग मुखर करने के लिए किया जाता है और डेटा को कभी वापस नहीं करना चाहिए, डेटा वापस करने के लिए स्टब्स का उपयोग किया जाता है और कभी भी जोर नहीं देना चाहिए।
dave1010

2
@ dave1010 मोक्स निश्चित रूप से डेटा वापस कर सकते हैं या एक अपवाद भी फेंक सकते हैं। उन्हें ऐसा करना चाहिए कि उनके द्वारा पारित किए गए जवाब में।
ट्रेंटन

2
@trenton यदि कोई वस्तु वापस आती है या डेटा के आधार पर फेंकता है तो यह नकली है , नकली नहीं। स्टब्स परीक्षण करते हैं कि आपके SUT संदेश प्राप्त करने का तरीका कैसे संभालते हैं , mocks परीक्षण करते हैं कि आपके SUT संदेश कैसे भेजते हैं । 2 को मिलाने से ओओ के खराब होने की संभावना है।
dave1010

8
मुझे लगता है कि यह बहुत अच्छा है - एक ठूंठ सवालों के जवाब देता है। एक नकली भी सवालों के जवाब देता है (एक ठूंठ है) लेकिन यह भी पुष्टि करता है कि सवाल पूछा गया था !!
लीफ

238

यहाँ वास्तविक दुनिया के नमूने के बाद हर एक का वर्णन है।

  • डमी - बस संतुष्ट करने के लिए फर्जी मूल्यों API

    उदाहरण : यदि आप किसी कक्षा की एक विधि का परीक्षण कर रहे हैं जिसके लिए एक निर्माणकर्ता में कई अनिवार्य मापदंडों की आवश्यकता होती है जिसका आपके परीक्षण पर कोई प्रभाव नहीं पड़ता है , तो आप वर्ग के नए उदाहरण बनाने के उद्देश्य से डमी ऑब्जेक्ट बना सकते हैं।

  • नकली - एक वर्ग का परीक्षण कार्यान्वयन बनाएं जो कुछ बाहरी बुनियादी ढांचे पर निर्भरता हो सकता है। (यह अच्छा अभ्यास है कि आपकी इकाई परीक्षा वास्तव में बाहरी बुनियादी ढांचे के साथ बातचीत नहीं करती है ।)

    उदाहरण : डेटाबेस तक पहुंचने के लिए नकली कार्यान्वयन बनाएं, इसे in-memoryसंग्रह के साथ बदलें ।

  • स्टब - ओवरराइड तरीकों को हार्ड-कोडित मानों को वापस करने के लिए, जिसे भी संदर्भित किया जाता है state-based

    उदाहरण : आपका परीक्षण वर्ग Calculate()पूर्ण होने में 5 मिनट लेने की विधि पर निर्भर करता है । 5 मिनट के इंतजार के बजाय आप इसके वास्तविक कार्यान्वयन को स्टब के साथ बदल सकते हैं जो हार्ड-कोडेड मान लौटाता है; समय का केवल एक छोटा सा अंश लेना।

  • नकली - बहुत मिलते-जुलते Stubलेकिन interaction-basedबल्कि राज्य आधारित है। इसका मतलब है कि आपको Mockकुछ मूल्य वापस करने की उम्मीद नहीं है , लेकिन यह मानने के लिए कि विधि कॉल के विशिष्ट क्रम बनाए गए हैं।

    उदाहरण: आप एक उपयोगकर्ता पंजीकरण कक्षा का परीक्षण कर रहे हैं। कॉल करने के बाद Saveउसे कॉल करना चाहिए SendConfirmationEmail

Stubsऔर Mocksवास्तव में उप प्रकार हैं Mock, दोनों परीक्षण कार्यान्वयन के साथ वास्तविक कार्यान्वयन को स्वैप करते हैं, लेकिन अलग-अलग, विशिष्ट कारणों के लिए।


175

में codeschool.com बेशक, रेल परीक्षण Zombies के लिए , वे मामले की इस परिभाषा दे:

ठूंठ

कोड के साथ एक विधि को बदलने के लिए जो एक निर्दिष्ट परिणाम देता है।

दिखावटी

विधि कहे जाने वाले जोर के साथ एक ठूंठ।

इसलिए जैसा कि सीन कोपेनहेवर ने अपने उत्तर में बताया है, अंतर यह है कि मॉक ने उम्मीदों को निर्धारित किया है (जैसे कि क्या कहा जाता है या कैसे उन्हें बुलाया जाता है)।


डिलन पोस्ट को पूरक करने के लिए, इस बारे में सोचें, आपके पास "मेककेक" नामक एक वर्ग है जो कई पुस्तकालय लेते हैं: दूध, अंडे, चीनी, ओवन।
अनारकली

139

स्टब्स आपके परीक्षणों को विफल नहीं करते हैं, नकली कर सकते हैं।


2
और मुझे लगता है कि यह अच्छा है, आप जानते हैं कि क्या परीक्षण के बाद एक ही व्यवहार होता है।
रोड्रीकिंग

1
@RodriKing मुझे वही एहसास है। मॉक के साथ के रूप में, उत्पादन कोड में किसी भी परिवर्तन के साथ - आपके पास परीक्षण कोड के अनुरूप परिवर्तन हैं। कौन सा दर्द है! स्टब्स के साथ, ऐसा लगता है कि आप व्यवहार का परीक्षण करते रहते हैं इसलिए परीक्षण कोड के साथ कोई सूक्ष्म परिवर्तन करने की आवश्यकता नहीं है।
tucq88

35

मुझे लगता है कि इस सवाल का सबसे सरल और स्पष्ट जवाब रॉय ओशेरोव ने अपनी पुस्तक द आर्ट ऑफ यूनिट टेस्टिंग में दिया है (पृष्ठ 85) में दिया है।

एक स्टब के साथ काम करने का सबसे आसान तरीका यह बताना है कि स्टब कभी भी परीक्षण को विफल नहीं कर सकता है। परीक्षण का उपयोग करता है हमेशा परीक्षण के तहत वर्ग के खिलाफ हैं।

दूसरी ओर, परीक्षण यह सत्यापित करने के लिए एक नकली वस्तु का उपयोग करेगा कि क्या परीक्षण विफल हुआ या नहीं। [...]

फिर से, मॉक ऑब्जेक्ट वह वस्तु है जिसका उपयोग हम यह देखने के लिए करते हैं कि परीक्षण विफल हुआ या नहीं।

इसका मतलब है कि अगर आप नकली के खिलाफ जोर दे रहे हैं तो इसका मतलब है कि आप नकली का उपयोग नकली के रूप में कर रहे हैं, यदि आप नकली का उपयोग केवल परीक्षण के बिना चलाने के लिए कर रहे हैं, तो आप ठूंठ के रूप में नकली का उपयोग कर रहे हैं।


2
मैं चाहता हूं कि आपका उत्तर शीर्ष पर पहुंच जाए। यहाँ पर आर। ओशेरोव इस youtu.be/fAb_OnooCsQ?t=1006 की व्याख्या कर रहे हैं ।
माइकल एकोका

31

उपरोक्त सभी स्पष्टीकरणों को पढ़ते हुए, मुझे संक्षेप में बताने का प्रयास करें:

  • स्टब : कोड का एक डमी टुकड़ा जो परीक्षण को चलाने देता है, लेकिन आपको परवाह नहीं है कि इसके साथ क्या होता है।
  • मॉक : कोड का एक डमी टुकड़ा, जिसे आप परीक्षण के भाग के रूप में सही ढंग से कहते हैं।
  • जासूस : कोड का एक डमी टुकड़ा, जो कोड के एक वास्तविक टुकड़े में कुछ कॉल को स्वीकार करता है, जिससे आपको संपूर्ण मूल ऑब्जेक्ट को बदलने के बिना कॉल को सत्यापित करने की अनुमति मिलती है।

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

जब मैंने यह उत्तर लिखा था तो मैंने जासूस के बारे में नहीं सुना था।
ओ'रोनी

23

एक मॉक सिर्फ व्यवहार का परीक्षण है, यह सुनिश्चित करता है कि कुछ तरीकों को कहा जाता है। Stub किसी विशेष वस्तु का एक परीक्षण योग्य संस्करण (प्रति se) है।

Apple तरीके से आपका क्या मतलब है?


19
"क्या मतलब है Apple रास्ता?"
कुबी

7
Microsoft तरीके से विरोध के रूप में Apple तरीके से :)
never_had_a_name

2
क्या यह किसी भी स्थिति में मदद करता है?
नेबुलाफॉक्स

21

यदि आप इसे डिबगिंग से तुलना करते हैं:

स्टब यह सुनिश्चित करने की तरह है कि कोई विधि सही मान लौटाती है

मॉक वास्तव में विधि में कदम रखने जैसा है और सुनिश्चित करता है कि सही मूल्य वापस करने से पहले अंदर सब कुछ सही हो।


20

एक मानसिक मॉडल का उपयोग करने से मुझे वास्तव में यह समझने में मदद मिली, बजाय सभी स्पष्टीकरण और लेखों के, जो काफी "सिंक" नहीं था।

कल्पना कीजिए कि आपके बच्चे की मेज पर एक कांच की प्लेट है और वह उसके साथ खेलना शुरू कर देता है। अब, आप डरते हैं कि यह टूट जाएगा। तो, आप उसे इसके बजाय एक प्लास्टिक की प्लेट दें। यह एक मॉक (समान व्यवहार, समान इंटरफ़ेस, "नरम" कार्यान्वयन) होगा।

अब, मान लीजिए कि आपके पास प्लास्टिक रिप्लेसमेंट नहीं है, इसलिए आप "यदि आप इसके साथ खेलना जारी रखते हैं, तो आप इसे तोड़ देंगे"। यह एक स्टब है , आपने पहले से एक पूर्वनिर्धारित राज्य प्रदान किया है।

एक डमी वह कांटा होगा जिसका उसने उपयोग भी नहीं किया था ... और एक स्पाई कुछ वैसा ही हो सकता है, जैसा आप पहले से उपयोग किए गए स्पष्टीकरण को प्रदान करते हैं।


19

मुझे लगता है कि उनके बीच सबसे महत्वपूर्ण अंतर उनके इरादों का है।

मुझे इसे WHY स्टब बनाम WHY मॉक में समझाने की कोशिश क्यों करनी चाहिए

मान लीजिए मैं अपने मैक ट्विटर क्लाइंट के पब्लिक टाइमलाइन कंट्रोलर के लिए टेस्ट कोड लिख रहा हूं

यहाँ परीक्षण नमूना कोड है

twitter_api.stub(:public_timeline).and_return(public_timeline_array)
client_ui.should_receive(:insert_timeline_above).with(public_timeline_array)
controller.refresh_public_timeline
  • STUB: Twitter API का नेटवर्क कनेक्शन बहुत धीमा है, जो मेरे टेस्ट को धीमा कर देता है। मुझे पता है कि यह समयसीमा लौटाएगा, इसलिए मैंने HTTP ट्विटर एपीआई का एक स्टब अनुकरण किया, ताकि मेरा परीक्षण इसे बहुत तेजी से चलाए, और मैं ऑफ़लाइन होने पर भी परीक्षण चला सकता हूं।
  • MOCK: मैंने अभी तक अपने किसी भी UI तरीके को नहीं लिखा है, और मुझे यकीन नहीं है कि मुझे अपने ui ऑब्जेक्ट के लिए कौन से तरीके लिखने होंगे। मुझे यह जानने की उम्मीद है कि परीक्षण कोड लिखकर मेरा नियंत्रक मेरी ui वस्तु के साथ कैसे सहयोग करेगा।

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

यदि आप मक्स के बारे में अधिक जानना चाहते हैं तो मैं इस लेख को पढ़ने का सुझाव देता हूं: http://jmock.org/oopsla2004.pdf


1
मुझे लगता है कि आपके पास सही विचार है, लेकिन डिलन किर्न्स ने इसे बहुत स्पष्ट रूप से समझाया।
ओ'रॉयनी

19

बहुत स्पष्ट और व्यावहारिक होने के लिए:

ठूंठ: एक वर्ग या वस्तु जो वर्ग / वस्तु के तरीकों को लागू करता है और नकली हो जाता है और हमेशा वही चाहता है जो आप चाहते हैं।

जावास्क्रिप्ट में उदाहरण:

var Stub = {
   method_a: function(param_a, param_b){
      return 'This is an static result';
   }
}

मॉक: स्टब के समान, लेकिन यह कुछ तर्क जोड़ता है जो "सत्यापित करता है" जब एक विधि कहा जाता है तो आप सुनिश्चित कर सकते हैं कि कुछ कार्यान्वयन उस पद्धति को बुला रहे हैं।

जैसा कि @Levan कहता है कि एक उदाहरण के रूप में कल्पना करें कि आप उपयोगकर्ता पंजीकरण कक्षा का परीक्षण कर रहे हैं। सेव को कॉल करने के बाद, इसे SendConfirmationEmail पर कॉल करना चाहिए।

एक बहुत ही बेवकूफ कोड उदाहरण:

var Mock = {
   calls: {
      method_a: 0
   }

   method_a: function(param_a, param_b){
     this.method_a++; 
     console.log('Mock.method_a its been called!');
   }
}

16

यह स्लाइड मुख्य अंतरों को बहुत अच्छा समझाती है।

यहां छवि विवरण दर्ज करें

* सीएसई 403 व्याख्यान 16 से, वाशिंगटन विश्वविद्यालय ("मार्टी स्टेप" द्वारा बनाई गई स्लाइड)


यह दो, IMO के बीच अंतर की अधिक स्पष्ट व्याख्या है। स्टब के लिए: परीक्षक स्टब लेते हैं और इसे सीधे परीक्षण के तहत कक्षा के अंदर उपयोग करते हैं। लेकिन मॉक के लिए, परीक्षक को यह बताना होगा कि मॉक ऑब्जेक्ट का उपयोग कैसे किया जाएगा। अलग-अलग मामलों में, यह अलग तरह से व्यवहार करेगा। इसके विपरीत, स्टब से अलग तरह से व्यवहार करने की उम्मीद नहीं की जाती है, लेकिन इसका उपयोग किया जाता है (जैसा कि जब भी संपर्क किया जाता है उसी डेटा को वापस करना)
Dexter

12

मुझे रॉय ओशेरोव [वीडियो लिंक] द्वारा डाला गया स्पष्टीकरण पसंद है ।

बनाई गई हर कक्षा या वस्तु एक नकली है। यदि आप इसके खिलाफ कॉल सत्यापित करते हैं तो यह एक नकली है। नहीं तो इसका ठूंठ।


12
  • स्टब्स बनाम मोक्स
    • स्टब्स
      1. तरीकों कॉल के लिए विशिष्ट उत्तर प्रदान करते हैं
        • ex: myStubbedService.getValues ​​() अभी परीक्षण के तहत कोड द्वारा आवश्यक स्ट्रिंग लौटाते हैं
      2. इसे अलग करने के लिए परीक्षण के तहत कोड द्वारा उपयोग किया जाता है
      3. परीक्षण विफल नहीं हो सकता
        • ex: myStubbedService.getValues ​​() बस स्टब किए गए मान को लौटाता है
      4. अक्सर अमूर्त तरीकों को लागू करते हैं
    • mocks
      1. स्टब्स के "सुपरसेट"; कह सकते हैं कि कुछ तरीकों को कहा जाता है
        • ex: सत्यापित करें कि myMockedService.getValues ​​() केवल एक बार कहा जाता है
      2. परीक्षण के तहत कोड के व्यवहार का परीक्षण करने के लिए उपयोग किया जाता है
      3. परीक्षण विफल हो सकता है
        • पूर्व: सत्यापित करें कि myMockedService.getValues ​​() एक बार बुलाया गया था; सत्यापन विफल हो जाता है, क्योंकि myMockedService.getValues ​​() को मेरे परीक्षण किए गए कोड द्वारा नहीं बुलाया गया था
      4. अक्सर मॉक इंटरफेस

11

आइए देखें टेस्ट डबल्स:

  • नकली : नकली ऐसी वस्तुएं होती हैं जिनके कार्यशील कार्यान्वयन होते हैं, लेकिन उत्पादन के समान नहीं। जैसे : डेटा एक्सेस ऑब्जेक्ट या रिपॉजिटरी का इन-मेमरी कार्यान्वयन।
  • स्टब : स्टब एक ऑब्जेक्ट है जो पूर्वनिर्धारित डेटा रखता है और परीक्षणों के दौरान कॉल का उत्तर देने के लिए इसका उपयोग करता है। जैसे : एक ऑब्जेक्ट जिसे डेटाबेस से कुछ डेटा हड़पने की ज़रूरत होती है ताकि एक विधि कॉल का जवाब दिया जा सके।

  • मोक्स : मोक्स वे ऑब्जेक्ट होते हैं जो कॉल रिसीव करते हैं जो उन्हें प्राप्त होते हैं। परीक्षण के दावे में, हम मोक्स पर सत्यापित कर सकते हैं कि सभी अपेक्षित कार्य किए गए थे। जैसे : एक कार्यक्षमता जो ई-मेल भेजने वाली सेवा को कॉल करती है। अधिक के लिए यह जाँच करें


1
मेरी राय में सबसे अच्छा जवाब
एरो स्टेफानो

9

एक नकली एक सामान्य शब्द है जिसका उपयोग या तो एक स्टब या मॉक ऑब्जेक्ट (हस्तलिखित या अन्यथा) का वर्णन करने के लिए किया जा सकता है, क्योंकि वे दोनों वास्तविक वस्तु की तरह दिखते हैं।

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

नकली सुनिश्चित करता है कि परीक्षण आसानी से चलता है। इसका मतलब है कि आपके भविष्य के परीक्षण के पाठक समझ जाएंगे कि नकली वस्तु का व्यवहार क्या होगा, इसके स्रोत कोड को पढ़ने की आवश्यकता के बिना (बाहरी संसाधन पर निर्भर होने की आवश्यकता के बिना)।

टेस्ट रन का मतलब क्या है?
नीचे दिए गए कोड में विदेशी मुद्रा:

 public void Analyze(string filename)
        {
            if(filename.Length<8)
            {
                try
                {
                    errorService.LogError("long file entered named:" + filename);
                }
                catch (Exception e)
                {
                    mailService.SendEMail("admin@hotmail.com", "ErrorOnWebService", "someerror");
                }
            }
        }

आप mailService.SendEMail () विधि का परीक्षण करना चाहते हैं , यह करने के लिए कि आपको परीक्षा पद्धति में अपवाद की आवश्यकता है, इसलिए आपको केवल उस परिणाम का अनुकरण करने के लिए एक Fake Stub त्रुटि सेवा वर्ग बनाने की आवश्यकता है, तब आपका परीक्षण कोड परीक्षण करने में सक्षम होगा mailService.SendEMail () विधि। जैसा कि आप देखते हैं कि आपको एक परिणाम की आवश्यकता है जो एक अन्य बाहरी निर्भरता त्रुटि सेवा वर्ग से है।


8

Jock के डेवलपर्स द्वारा कागज मॉक रोल्स से नहीं , वस्तुओं से ही सही :

स्टब्स उत्पादन कोड के डमी कार्यान्वयन हैं जो डिब्बाबंद परिणाम लौटाते हैं। मॉक ऑब्जेक्ट्स स्टब्स के रूप में कार्य करते हैं, लेकिन इसमें अपने पड़ोसियों के साथ लक्ष्य ऑब्जेक्ट के इंटरैक्शन को शामिल करने के लिए दावे भी शामिल हैं।

तो, मुख्य अंतर हैं:

  • स्टब्स पर सेट की गई अपेक्षाएं आमतौर पर सामान्य होती हैं, जबकि मोक्स पर सेट की गई अपेक्षाएं अधिक "चतुर" हो सकती हैं (उदाहरण के लिए पहली कॉल पर इसे लौटाएं, दूसरे पर यह)।
  • स्टब्स मुख्य रूप से SUT के अप्रत्यक्ष इनपुट को सेटअप करने के लिए उपयोग किया जाता है , जबकि mocks का उपयोग SUT के अप्रत्यक्ष इनपुट और अप्रत्यक्ष आउटपुट दोनों का परीक्षण करने के लिए किया जा सकता है ।

योग करने के लिए, जबकि फाउलर के लेख शीर्षक से भ्रम को फैलाने की कोशिश की जा रही है : मोज़ेक स्टब्स हैं, लेकिन वे केवल स्टब्स नहीं हैं


1
मुझे लगता है कि आप सही हैं, लेकिन यही कारण है कि फाउलर लेख भ्रामक है, लेख का शीर्षक "मोक्स आर स्टब्स" नहीं है ... लेकिन वे हैं ?! ¯_ (¯) _ / ¯
स्टोनडॉउग

@stonedauwg, वास्तव में, मैंने आपकी सजा और स्पष्टीकरण को शामिल करने के लिए अपनी पोस्ट को संपादित किया। उम्मीद है यह कुछ और काम आएगा।
डिमोस सेप

@stonedauwg, एक मज़ाक एक ठूंठ नहीं है, जैसे एक आयत एक वर्ग नहीं है। :)
सीनियोरडान ०

7

मैं द आर्ट ऑफ़ यूनिट टेस्टिंग पढ़ रहा था , और निम्नलिखित परिभाषा पर ठोकर खाई:

एक नकली एक सामान्य शब्द है जिसका उपयोग या तो एक स्टब या मॉक ऑब्जेक्ट (हस्तलिखित या अन्यथा) का वर्णन करने के लिए किया जा सकता है, क्योंकि वे दोनों वास्तविक वस्तु की तरह दिखते हैं। क्या कोई नकली एक स्टब है या नकली यह इस बात पर निर्भर करता है कि वर्तमान परीक्षण में इसका उपयोग कैसे किया जाता है। यदि इसका उपयोग किसी इंटरैक्शन की जांच करने के लिए किया जाता है (इसके विरुद्ध दावा किया गया है), तो यह एक नकली वस्तु है । अन्यथा, यह एक ठूंठ है


5

मुझे अंकलबॉच द लिटिल मॉकर के इस दिलचस्प लेख से पता चला । यह सभी शब्दावली को बहुत आसान तरीके से समझाता है, इसलिए शुरुआती लोगों के लिए यह उपयोगी है। मार्टिन फाउलर्स लेख विशेष रूप से मेरे जैसे शुरुआती लोगों के लिए एक कठिन पढ़ा गया है।


4

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

नकली एक नकली वस्तु है जो परीक्षण चलाता है। जहाँ हम जोर देते हैं।


"इसलिए डेटाबेस के साथ सीधे बातचीत के बजाय हम हशमप के साथ बातचीत करते हैं।" ... क्योंकि whe के पास डेटाबेस-मॉड्यूल कोड करने के लिए अभी तक कोई समय नहीं था, और हम स्टब का उपयोग किए बिना परीक्षण-कोड नहीं चला सकते थे। अन्यथा बहुत ही हसपैम एक नकली होगा! सही?
बोरिस डैपेन

4

सी # और Moq फ्रेमवर्क का उपयोग करके मॉक बनाम स्टब्स के उदाहरण देखें। Moq में स्टब के लिए एक विशेष कीवर्ड नहीं है, लेकिन आप स्टब्स बनाने के लिए मॉक ऑब्जेक्ट का भी उपयोग कर सकते हैं।

namespace UnitTestProject2
{
    using Microsoft.VisualStudio.TestTools.UnitTesting;
    using Moq;
    [TestClass]
    public class UnitTest1
    {
        /// <summary>
        /// Test using Mock to Verify that GetNameWithPrefix method calls Repository GetName method "once" when Id is greater than Zero
        /// </summary>
        [TestMethod]
        public void GetNameWithPrefix_IdIsTwelve_GetNameCalledOnce()
        {
            // Arrange 
            var mockEntityRepository = new Mock<IEntityRepository>();
            mockEntityRepository.Setup(m => m.GetName(It.IsAny<int>()));

            var entity = new EntityClass(mockEntityRepository.Object);
            // Act 
            var name = entity.GetNameWithPrefix(12);
            // Assert
            mockEntityRepository.Verify(m => m.GetName(It.IsAny<int>()), Times.Once);
        }
        /// <summary>
        /// Test using Mock to Verify that GetNameWithPrefix method doesn't call Repository GetName method when Id is Zero
        /// </summary>
        [TestMethod]
        public void GetNameWithPrefix_IdIsZero_GetNameNeverCalled()
        {
            // Arrange 
            var mockEntityRepository = new Mock<IEntityRepository>();
            mockEntityRepository.Setup(m => m.GetName(It.IsAny<int>()));
            var entity = new EntityClass(mockEntityRepository.Object);
            // Act 
            var name = entity.GetNameWithPrefix(0);
            // Assert
            mockEntityRepository.Verify(m => m.GetName(It.IsAny<int>()), Times.Never);
        }
        /// <summary>
        /// Test using Stub to Verify that GetNameWithPrefix method returns Name with a Prefix
        /// </summary>
        [TestMethod]
        public void GetNameWithPrefix_IdIsTwelve_ReturnsNameWithPrefix()
        {
            // Arrange 
            var stubEntityRepository = new Mock<IEntityRepository>();
            stubEntityRepository.Setup(m => m.GetName(It.IsAny<int>()))
                .Returns("Stub");
            const string EXPECTED_NAME_WITH_PREFIX = "Mr. Stub";
            var entity = new EntityClass(stubEntityRepository.Object);
            // Act 
            var name = entity.GetNameWithPrefix(12);
            // Assert
            Assert.AreEqual(EXPECTED_NAME_WITH_PREFIX, name);
        }
    }
    public class EntityClass
    {
        private IEntityRepository _entityRepository;
        public EntityClass(IEntityRepository entityRepository)
        {
            this._entityRepository = entityRepository;
        }
        public string Name { get; set; }
        public string GetNameWithPrefix(int id)
        {
            string name = string.Empty;
            if (id > 0)
            {
                name = this._entityRepository.GetName(id);
            }
            return "Mr. " + name;
        }
    }
    public interface IEntityRepository
    {
        string GetName(int id);
    }
    public class EntityRepository:IEntityRepository
    {
        public string GetName(int id)
        {
            // Code to connect to DB and get name based on Id
            return "NameFromDb";
        }
    }
}

4

स्टब और मॉक परीक्षण बिंदु:

  • स्टब डमी कार्यान्वयन है जिसे स्थिर तरीके से उपयोगकर्ता द्वारा किया जाता है अर्थात स्टब में कार्यान्वयन कोड लिखना। इसलिए यह सेवा की परिभाषा और गतिशील स्थिति को संभाल नहीं सकता है, आम तौर पर यह जॉकिट ढांचे में मॉकिंग ढांचे का उपयोग किए बिना किया जाता है।

  • मॉक भी डमी कार्यान्वयन है लेकिन इसके कार्यान्वयन ने मॉकिटो जैसे मॉकिंग फ्रेमवर्क का उपयोग करके गतिशील तरीके से किया। इसलिए हम हालत और सेवा की परिभाषा को गतिशील तरीके से संभाल सकते हैं यानी रनटाइम पर कोड से मोक्स को गतिशील रूप से बनाया जा सकता है। इसलिए नकली का उपयोग करके हम स्टब्स को गतिशील रूप से लागू कर सकते हैं।


3

प्लस उपयोगी उत्तर, सब्क्स की तुलना में मोक्स का उपयोग करने का सबसे शक्तिशाली बिंदु

यदि सहयोगी [जो मुख्य कोड इस पर निर्भर करता है] हमारे नियंत्रण में नहीं है (उदाहरण के लिए एक तृतीय-पक्ष लाइब्रेरी से),
इस मामले में, स्टॉक मॉक के बजाय लिखना मुश्किल है


2

मैंने मतभेदों को स्पष्ट करने के लिए अपने उत्तर में पायथन उदाहरणों का उपयोग किया है।

स्टब - स्टबिंग एक सॉफ्टवेयर डेवलपमेंट तकनीक है जिसका उपयोग विकास के जीवन-चक्र में शुरुआती कक्षाओं के तरीकों को लागू करने के लिए किया जाता है। वे आमतौर पर एक ज्ञात इंटरफ़ेस के कार्यान्वयन के लिए प्लेसहोल्डर के रूप में उपयोग किए जाते हैं, जहां इंटरफ़ेस को अंतिम रूप दिया जाता है या ज्ञात होता है, लेकिन कार्यान्वयन अभी तक ज्ञात या अंतिम रूप से ज्ञात नहीं है। आप स्टब्स से शुरू करते हैं, जिसका सीधा सा मतलब है कि आप केवल एक फंक्शन की परिभाषा लिखते हैं और बाद के लिए वास्तविक कोड छोड़ देते हैं। लाभ यह है कि आप तरीकों को नहीं भूलेंगे और आप इसे कोड में देखते हुए अपने डिजाइन के बारे में सोचना जारी रख सकते हैं। आप अपने स्टब को एक स्थिर प्रतिक्रिया भी दे सकते हैं ताकि प्रतिक्रिया का उपयोग आपके कोड के अन्य भागों द्वारा तुरंत किया जा सके। स्टब ऑब्जेक्ट एक मान्य प्रतिक्रिया प्रदान करते हैं, लेकिन यह स्थिर है कि आप किस इनपुट में पास होते हैं, आपको हमेशा एक ही प्रतिक्रिया मिलेगी:

class Foo(object):
    def bar1(self):
        pass

    def bar2(self):
        #or ...
        raise NotImplementedError

    def bar3(self):
        #or return dummy data
        return "Dummy Data"

दिखावटी ऑब्जेक्ट्स का उपयोग मॉक टेस्ट मामलों में किया जाता है जो यह पुष्टि करते हैं कि उन वस्तुओं पर कुछ निश्चित तरीके कहलाते हैं। नकली वस्तुएं नकली वस्तुएं हैं जो वास्तविक वस्तुओं के व्यवहार को नियंत्रित तरीकों से नकल करती हैं। आप आमतौर पर किसी अन्य वस्तु के व्यवहार का परीक्षण करने के लिए एक नकली वस्तु बनाते हैं। मोक्स हमें उन संसाधनों का अनुकरण करते हैं जो या तो अनुपलब्ध हैं या यूनिट टेस्टिंग के लिए बहुत ही अनिर्दिष्ट हैं।

mymodule.py:

import os
import os.path

def rm(filename):
    if os.path.isfile(filename):
        os.remove(filename)

test.py:

from mymodule import rm
import mock
import unittest

class RmTestCase(unittest.TestCase):
    @mock.patch('mymodule.os')
    def test_rm(self, mock_os):
        rm("any path")
        # test that rm called os.remove with the right parameters
        mock_os.remove.assert_called_with("any path")

if __name__ == '__main__':
    unittest.main()

यह एक बहुत ही बुनियादी उदाहरण है जो सिर्फ rm चलाता है और उस पैरामीटर को बताता है जिसके साथ इसे बुलाया गया था। आप यहां दिखाए गए कार्यों के साथ न केवल मॉक का उपयोग कर सकते हैं, और आप एक मान भी लौटा सकते हैं ताकि परीक्षण के लिए स्टब को बदलने के लिए मॉक ऑब्जेक्ट का उपयोग किया जा सके।

अधिक unittest.mock पर , python में नोट 2.x मॉक को unittest में शामिल नहीं किया गया है लेकिन एक डाउनलोड करने योग्य मॉड्यूल है जिसे पाइप (pip install मॉक) के माध्यम से डाउनलोड किया जा सकता है।

मैंने रॉय ओशेरोव की "द आर्ट ऑफ़ यूनिट टेस्टिंग" भी पढ़ी है और मुझे लगता है कि पायथन और पायथन उदाहरणों का उपयोग करते हुए इसी तरह की किताब लिखी जाए तो बहुत अच्छा होगा। अगर किसी को ऐसी किताब के बारे में पता हो तो कृपया शेयर जरूर करें। चियर्स :)


2

स्टब एक नकली वस्तु है जिसे परीक्षण के उद्देश्य से बनाया गया है। एक नकली एक स्टब है जो रिकॉर्ड करता है कि क्या अपेक्षित कॉल प्रभावी रूप से हुई है।


2

एक स्टब एक खाली कार्य है जिसका उपयोग परीक्षणों के दौरान बिना किसी अपवाद के बचने के लिए किया जाता है:

function foo(){}

एक नकली एक कृत्रिम कार्य है जो परीक्षण के दौरान ओएस, पर्यावरण या हार्डवेयर निर्भरता से बचने के लिए उपयोग किया जाता है:

function foo(bar){ window = this; return window.toString(bar); }

कथनों और स्थिति के संदर्भ में:

  • एक घटना या राज्य परिवर्तन से पहले मोक्स का दावा किया जाता है
  • स्टब्स का दावा नहीं किया जाता है, वे असंबंधित इकाइयों से कोड निष्पादित करने से बचने के लिए एक घटना से पहले राज्य प्रदान करते हैं
  • जासूस स्टब्स की तरह सेटअप होते हैं, फिर एक घटना या राज्य परिवर्तन के बाद जोर दिया जाता है
  • नकली होने का दावा नहीं किया जाता है, वे राज्य से बचने के लिए हार्डकॉन्ड निर्भरता के साथ एक घटना के बाद चलते हैं

संदर्भ


2
शब्दावली में जासूस जोड़ने के लिए +1। इसके अलावा, मुझे लगता है कि आप का अर्थ है "जासूसों की तरह सेटअप हैं" नहीं "जासूस स्टब्स की तरह सेटअप हैं"
समान दिवा


2

एक नकली एक तकनीकी और एक कार्यात्मक वस्तु दोनों है ।

मॉक तकनीकी है । यह वास्तव में एक मॉकिंग लाइब्रेरी (ईज़ीमॉक, जेमॉकिट और हाल ही में मॉकिटो इन के लिए जाना जाता है) द्वारा बनाया गया है, बाइट कोड पीढ़ी के लिए धन्यवाद ।
नकली कार्यान्वयन है उत्पन्न एक तरह से हम कहाँ सकता है में साधन यह जब एक विधि शुरू हो जाती है एक विशिष्ट मूल्य बल्कि यह सत्यापित करते हुए एक नकली विधि कुछ विशिष्ट मानकों (सख्त जांच) या जो कुछ भी मानकों के साथ लागू किया गया था के रूप में कुछ अन्य बातों के वापस जाने के लिए ( कोई सख्त जाँच नहीं)।

एक झटके का संकेत:

@Mock Foo fooMock

एक व्यवहार रिकॉर्डिंग:

when(fooMock.hello()).thenReturn("hello you!");

आह्वान सत्यापित करना:

verify(fooMock).hello()

ये स्पष्ट रूप से फू कक्षा / व्यवहार को पलटने / ओवरराइड करने का स्वाभाविक तरीका नहीं हैं। इसलिए मैं एक तकनीकी पहलू का उल्लेख करता हूं।

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


स्टब सिर्फ एक कार्यात्मक वस्तु है: यह उस वर्ग का एक उदाहरण है जिसे हमें SUT से अलग करने की आवश्यकता है और यह सब है। इसका मतलब है कि हमारे यूनिट परीक्षणों के दौरान आवश्यक स्टब क्लास और सभी व्यवहार फिक्स्चर दोनों को स्पष्ट रूप से परिभाषित किया जाना है।
उदाहरण के लिए, स्टब hello()को वर्ग को उप- Fooवर्ग (या इसके इंटरफ़ेस को लागू करने के लिए इसे लागू करना होगा) और ओवरराइड करने की आवश्यकता होगी hello() :

public class HelloStub extends Hello{    
  public String hello { 
      return "hello you!"; 
  }
}

यदि किसी अन्य परीक्षण परिदृश्य को एक और मान वापसी की आवश्यकता होती है, तो शायद हमें रिटर्न सेट करने के लिए एक सामान्य तरीका परिभाषित करना होगा:

public class HelloStub extends Hello{    
  public HelloStub(String helloReturn){
       this.helloReturn = helloReturn;
  }
  public String hello { 
      return helloReturn; 
  }
}

अन्य परिदृश्य: यदि मेरे पास एक साइड इफेक्ट विधि (कोई वापसी नहीं) थी और मैं जांच करूंगा कि उस विधि को लागू किया गया था, तो मुझे शायद स्टूल वर्ग में एक बूलियन या एक काउंटर जोड़ना चाहिए ताकि यह गिन सके कि विधि कितनी बार लागू हुई थी।


निष्कर्ष

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


मार्टिन फाउलर लेख के बारे में: मुझे लगता है कि मैं "मॉकिस्ट" प्रोग्रामर नहीं हूं जबकि मैं मोक्स का उपयोग करता हूं और मैं स्टब्स से बचता हूं।
लेकिन मैं नकली का उपयोग करता हूं जब यह वास्तव में आवश्यक (कष्टप्रद निर्भरताएं) होती है और मैं परीक्षण स्लाइसिंग और मिनी-एकीकरण परीक्षण का पक्ष लेता हूं जब मैं निर्भरता वाले एक वर्ग का परीक्षण करता हूं जो कि ओवरहेडिंग होगा।

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