क्या मोक्स ओपन / बंद सिद्धांत का उल्लंघन करते हैं?


13

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

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

मॉक बनाम स्टब पर शोध करते समय , कई लेख इस बात से सहमत हैं कि स्टॉक्स को मॉक के बजाय इस्तेमाल किया जाना चाहिए, क्योंकि वे निर्भरता से अपेक्षाओं पर भरोसा नहीं करते हैं, जिसका अर्थ है कि परीक्षण कार्यान्वयन के तहत अंतर्निहित प्रणाली के ज्ञान की आवश्यकता नहीं है।

मेरे प्रश्न होंगे:

  1. क्या मोक्स खुले / बंद सिद्धांत का उल्लंघन करते हैं?
  2. क्या पिछले पैराग्राफ पर स्टब्स के पक्ष में तर्क में कुछ कमी है, जो स्टब्स को इतने महान बनाम मोक्स नहीं बनाते हैं?
  3. यदि हां, तो मॉक करने के लिए एक अच्छा उपयोग मामला कब होगा और स्टब्स का उपयोग करने के लिए एक अच्छा उपयोग मामला कब होगा?


8
Since mocking relays heavily on expectation calls from system under test's dependencies...मुझे लगता है कि यह वह जगह है जहां आप जा रहे हैं। एक नकली एक बाहरी प्रणाली का कुछ कृत्रिम प्रतिनिधित्व है। यह किसी भी तरह से बाहरी प्रणाली का प्रतिनिधित्व नहीं करता है, इंफोर्स को छोड़कर, क्योंकि यह बाहरी प्रणाली को इस तरह से अनुकरण करता है कि यह कोड को बाहरी प्रणाली पर निर्भरता वाले कोड के खिलाफ परीक्षण चलाने की अनुमति देता है। आपको यह साबित करने के लिए एकीकरण परीक्षणों की आवश्यकता होगी कि आपका कोड वास्तविक, बिना सिस्टम
रॉबर्ट हार्वे

8
इसे दूसरे तरीके से रखने के लिए, मॉक एक वैकल्पिक कार्यान्वयन है। यही कारण है कि हमने पहले स्थान पर एक इंटरफ़ेस के लिए प्रोग्राम किया, ताकि हम वास्तविक कार्यान्वयन के लिए स्टैंड के रूप में नकली का उपयोग कर सकें। दूसरे शब्दों में, mocks कर रहे हैं से decoupled, करने के लिए, वास्तविक क्रियान्वयन युग्मित नहीं।
रॉबर्ट हार्वे

3
"दूसरे शब्दों में, एक परीक्षण विफल होना चाहिए अगर विधि काम नहीं करती है, लेकिन इसलिए नहीं कि कार्यान्वयन बदल गया", यह हमेशा सच नहीं होता है। ऐसी बहुत सी परिस्थितियाँ हैं जहाँ आपको अपने कार्यान्वयन और परीक्षणों दोनों को बदलना चाहिए।
whatsisname

जवाबों:


4
  1. मैं यह नहीं देखता कि नकली खुले / बंद सिद्धांत का उल्लंघन क्यों करेंगे। यदि आप हमें समझा सकते हैं कि आपको क्यों लगता है कि वे हो सकते हैं, तो हम आपकी चिंताओं को दूर करने में सक्षम हो सकते हैं।

  2. स्टब्स का एकमात्र नुकसान जो मैं सोच सकता हूं, वह यह है कि उन्हें आमतौर पर मोक्स से लिखने के लिए अधिक काम करने की आवश्यकता होती है, क्योंकि उनमें से हर एक वास्तव में एक निर्भर इंटरफ़ेस का वैकल्पिक कार्यान्वयन है, इसलिए इसे आम तौर पर एक पूर्ण (या पूरी तरह से) प्रदान करना होता है आश्रित इंटरफ़ेस का कार्यान्वयन। आपको एक चरम उदाहरण देने के लिए, यदि परीक्षण के तहत आपका सबसिस्टम आरडीबीएमएस को आमंत्रित करता है, तो आरडीबीएमएस का एक नकली परीक्षण के डेटा के पूर्व निर्धारित सेटों को परीक्षण के तहत उप-प्रणाली द्वारा जारी किए जाने वाले विशिष्ट प्रश्नों का जवाब देगा। दूसरी ओर, एक वैकल्पिक कार्यान्वयन एक पूर्ण विकसित इन-मेमोरी आरडीबीएमएस होगा, संभवतः उत्पादन पर उपयोग किए जा रहे वास्तविक क्लाइंट-सर्वर आरडीबीएमएस के quirks का अनुकरण करने के अतिरिक्त बोझ के साथ। (सौभाग्य से, हमारे पास HSQLDB जैसी चीजें हैं, इसलिए हम वास्तव में ऐसा कर सकते हैं, लेकिन फिर भी,

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

PS जिस व्यक्ति का आप उल्लेख कर रहे हैं वह मुझे हो सकता है, मेरे अन्य परीक्षण-संबंधित जवाबों में से एक में programmers.stackexchange.com पर, उदाहरण के लिए यह एक


an alternative implementation would be a full-blown in-memory RDBMS- आप जरूरी नहीं कि एक ठूंठ के साथ दूर जाना है।
रॉबर्ट हार्वे

@RobertHarvey अच्छी तरह से, HSQLDB और H2 के साथ वास्तव में इतनी दूर जाना मुश्किल नहीं है। शायद अब तक जाने के लिए आधे-अधूरे काम करना अधिक कठिन है । लेकिन यदि आप इसे अपने दम पर करने का निर्णय लेते हैं, तो आपको SQL पार्सर लिखकर शुरू करना होगा। ज़रूर, आप कुछ कोनों को काट सकते हैं, लेकिन बहुत काम है । वैसे भी, जैसा कि मैंने ऊपर कहा, यह सिर्फ एक चरम उदाहरण है।
माइक नकीस

9
  1. ओपन / क्लोज्ड सिद्धांत ज्यादातर वर्ग के व्यवहार को संशोधित किए बिना बदलने में सक्षम होने के बारे में है। इसलिए, परीक्षण के तहत एक वर्ग के अंदर नकली घटक निर्भरता को इंजेक्ट करना इसका उल्लंघन नहीं करता है।

  2. परीक्षण डबल्स (मॉक / स्टब) के साथ समस्या यह है कि आप मूल रूप से मनमानी धारणा बनाते हैं कि परीक्षण के तहत वर्ग किस तरह से अपने पर्यावरण के साथ बातचीत करता है। यदि वे अपेक्षाएँ गलत हैं, तो कोड के लागू होने के बाद आपको कुछ समस्याएं होने की संभावना है। यदि आप इसे वहन कर सकते हैं, तो अपने उत्पादन पर्यावरण को सीमित करने की तुलना में समान बाधाओं के भीतर अपने कोड का परीक्षण करें। यदि आप नहीं कर सकते हैं, तो कम से कम मान्यताओं को संभव बनाएं, और केवल आपके सिस्टम (डेटाबेस, प्रमाणीकरण सेवा, HTTP क्लाइंट, आदि ...) के परिधीयों को मॉक / स्टब करें।

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


6

नोट: मैं मान रहा हूं कि आप मॉक को परिभाषित कर रहे हैं, "बिना किसी कार्यान्वयन के साथ एक वर्ग, बस कुछ चीज़ों पर आप नज़र रख सकते हैं" और स्टब को "आंशिक मॉक, उर्फ ​​कार्यान्वित वर्ग के कुछ वास्तविक व्यवहार का उपयोग करता है", इस स्टैक के अनुसार अतिप्रवाह प्रश्न

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

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

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

यह दस्तावेज कहता है कि मैं इससे बेहतर कर सकता हूं। मोज़ेक का उपयोग करने से आपको बस यह परखने की अनुमति मिलती है कि एक विशेष वर्ग, और कुछ नहीं; यदि आपको उस व्यवहार को प्राप्त करने के लिए आंशिक मोक्स की आवश्यकता है जिसे आप ढूंढ रहे हैं, तो आपने शायद कुछ गलत किया है, एसआरपी का उल्लंघन कर रहे हैं, और आगे, और आपका कोड एक रिफ्लेक्टर खड़ा कर सकता है। मोक्स खुले-बंद सिद्धांत का उल्लंघन नहीं करते हैं, क्योंकि वे केवल कभी भी परीक्षण में उपयोग किए जाते हैं, वे उस कोड में वास्तविक परिवर्तन नहीं हैं। आमतौर पर वे cglib जैसे पुस्तकालय द्वारा किसी भी तरह से मक्खी पर उत्पन्न होते हैं।


2
एक ही प्रदान किए गए SO प्रश्न (स्वीकृत उत्तर) से, यह मॉक / स्टब परिभाषा है जिसका मैं भी उल्लेख कर रहा था: नकली वस्तुओं का उपयोग अपेक्षाओं को परिभाषित करने के लिए किया जाता है: इस परिदृश्य में मुझे उम्मीद है कि A () को ऐसे और ऐसे मापदंडों के साथ बुलाया जाएगा। ऐसी अपेक्षाओं को रिकॉर्ड करता है और सत्यापित करता है। दूसरी ओर, स्टब्स का एक अलग उद्देश्य होता है: वे अपेक्षाओं को रिकॉर्ड या सत्यापित नहीं करते हैं, बल्कि हमें परीक्षण परिदृश्य का उपयोग करने के लिए "नकली" वस्तु की स्थिति को "प्रतिस्थापित" करने की अनुमति देते हैं ...
क्रिस्टोफर फ्रांसिस्को

2

मुझे लगता है कि मुद्दा इस धारणा से उत्पन्न हो सकता है कि एकमात्र वैध परीक्षण वे हैं जो खुले / बंद परीक्षण से मिलते हैं।

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

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

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

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