मॉकिंग कंक्रीट क्लास - अनुशंसित नहीं है


11

मैंने अभी "ग्रोइंग ऑब्जेक्ट-ओरिएंटेड सॉफ़्टवेयर" पुस्तक का एक अंश पढ़ा है जो कुछ कारणों की व्याख्या करता है कि कंक्रीट क्लास की सिफारिश क्यों नहीं की जाती है।

यहां म्यूज़िक वेबकैम क्लास के लिए यूनिट-टेस्ट के कुछ सैंपल कोड:

public class MusicCentreTest {
  @Test public void startsCdPlayerAtTimeRequested() {
    final MutableTime scheduledTime = new MutableTime();
    CdPlayer player = new CdPlayer() { 
      @Override 
      public void scheduleToStartAt(Time startTime) {
        scheduledTime.set(startTime);
      }
    }

    MusicCentre centre = new MusicCentre(player);
    centre.startMediaAt(LATER);

    assertEquals(LATER, scheduledTime.get());
  }
}

और उनकी पहली व्याख्या:

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

मैं ठीक-ठीक पता नहीं लगा सकता कि उसके कहने का क्या मतलब है:

इससे यह देखना कठिन हो जाता है कि क्या इस रिश्ते का समर्थन करने वाली सेवा कहीं और प्रासंगिक हो सकती है और मुझे अगली बार कक्षा के साथ काम करने के बाद फिर से विश्लेषण करना होगा।

मैं समझता हूँ कि सेवा MusicCentreनामक विधि से मेल खाती है startMediaAt

"अन्यत्र" से उसका क्या अर्थ है?

पूरा अंश यहाँ है: http://www.mockobjects.com/2007/04/test-smell-mocking-concrete-classes.html


उनके ब्लॉग पर एक टिप्पणी जोड़ी गई, क्योंकि मैं यह पता लगाने में असमर्थ था कि वह इन उद्धरणों से क्या मतलब है।
oligofren

@oligofren यह वास्तव में एक महान पहेली है :) ...
1237

जवाबों:


6

उस पोस्ट के लेखक सदस्य वर्गों के उपयोग पर इंटरफेसेस के उपयोग को बढ़ावा दे रहे हैं।

It turns out that my MusicCentre object only uses the starting and stopping methods on the CdPlayer, the rest are used by some other part of the system. I'm over-specifying my MediaCentre by requiring it to talk to a CdPlayer, what it actually needs is a ScheduledDevice.

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

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

दावा तब शुरू होता है जब आप सभी संभावित कार्यक्षमता को विस्फोट कर देते हैं:

  • शुरू
  • रुकें
  • ठहराव
  • अभिलेख
  • यादृच्छिक खेलने का क्रम
  • नमूना पटरियों, गीत की शुरुआत
  • नमूना पटरियों, गीत का यादृच्छिक नमूना
  • मीडिया जानकारी प्रदान करें
  • ...

अब "मुझे सिर्फ शुरुआत और ठहराव चाहिए" का उनका दावा अधिक मायने रखता है। इंटरफ़ेस के बजाय ठोस सदस्य ऑब्जेक्ट का उपयोग करना भविष्य के डेवलपर्स के लिए कम स्पष्ट है क्योंकि वास्तव में इसकी आवश्यकता है। CdPlayer के भीतर अन्य सभी कार्यों पर MediaScript से रनिंग यूनिट परीक्षण, परीक्षण के प्रयास की बर्बादी है क्योंकि वे "देखभाल" राज्य से संबंधित नहीं हैं। यदि Recordफ़ंक्शन इस मामले में काम नहीं कर रहा था, तो हम वास्तव में परवाह नहीं करते हैं क्योंकि यह आवश्यक नहीं है। लेकिन भविष्य का अनुचर जरूरी नहीं जानता होगा कि कोड के आधार पर, जैसा कि लिखा गया है।

अंतत: लेखक का आधार केवल उसी चीज का उपयोग करना है, जिसकी आवश्यकता है और भविष्य के अनुरक्षकों को यह स्पष्ट करना है कि पहले क्या आवश्यक था। लक्ष्य बाद के रखरखाव के दौरान कोड के मॉड्यूल को rework / reanalyzing को कम करना है।


इस बेहतरीन जवाब के लिए धन्यवाद। हालाँकि आपने कहा था: "सभी अन्य कार्यों पर इकाई परीक्षण चलाना परीक्षण के प्रयास की बर्बादी है क्योंकि वे" परवाह नहीं करते "राज्य के हैं।" क्या यह नहीं है: "अन्य कार्यों में से प्रत्येक के लिए नकली बनाना परीक्षण के प्रयास की बर्बादी है क्योंकि वे" देखभाल "राज्य से संबंधित हैं।"
मिक 378

@ Mik378 - हाँ, यह वही है जो मुझे मिल रहा था, मैंने इसे अलग तरह से व्यक्त किया। और मैंने अपने उत्तर को और अधिक स्पष्ट करने के लिए अद्यतन किया।

लेकिन मुझे लगता है कि "रनिंग यूनिट टेस्ट" शब्द भ्रामक है। इसका मतलब यह होगा कि म्यूज़िशव्यू अपने सहयोगी के यूनिट-टेस्ट के बारे में है ... जबकि वास्तव में यह अपने सहयोगी को यूनिट-टेस्ट करने के लिए अपने सहयोगी को MOCKS करता है। वैसे, अब मैं इसका अर्थ समझ रहा हूं :)
मिक 378

@ मिक 378 - हम एक ही बात कह रहे हैं, और ऐसा करने के लिए मैं शायद सटीक शब्दावली से कम का उपयोग कर रहा हूं। भ्रम के लिए क्षमा याचना।

4

इससे यह देखना कठिन हो जाता है कि क्या इस रिश्ते का समर्थन करने वाली सेवा कहीं और प्रासंगिक हो सकती है और मुझे अगली बार कक्षा के साथ काम करने के बाद फिर से विश्लेषण करना होगा।

इसके बारे में बहुत सोचने के बाद, मुझे इस उद्धरण की एक संभावित व्याख्या मिलती है:

उद्धृत "सेवा" "समय-निर्धारण के तथ्य" से मेल खाती है। यह "शेड्यूल्डडेविस" नामक एक अच्छी तरह से नामित और "फ़ोकस-ऑन-वन-रोल" इंटरफ़ेस द्वारा व्यक्त किया जा सकता है या किसी भी इंटरफेस के आधार पर ठोस विधि कार्यान्वयन द्वारा व्यक्त किया जा सकता है।

ऊपर दिए गए नमूने में, शेड्यूलिंग को संपूर्ण पूर्ण विशेषताओं वाली वस्तु द्वारा व्यक्त किया गया है CDPlayer। इस प्रकार, यह अभी भी MusicCentre"शेड्यूलिंग के तथ्य" के बीच अंतर्निहित संबंध की ओर जाता है ।

इसलिए यदि हम ठोस वर्गों को इंजेक्ट करना शुरू करते हैं और उन्हें उच्च-स्तरीय वस्तुओं में उड़ाते हैं; जब हम इन लोगों का परीक्षण करना चाहते हैं, तो हमें प्रत्येक इंजेक्ट की गई "ठोस" वस्तुओं का विश्लेषण करना होगा, यह देखने के लिए कि क्या यह एक विशिष्ट संबंध प्रस्तुत करता है जिसे हम अपने आप में छिपाते हैं क्योंकि वे छिपी हैं (निहित)। इसके विपरीत, इंटरफ़ेस पर कोडिंग ALWAYS डेवलपर को सीधे यह पता लगाने की अनुमति देता है कि उच्च-स्तरीय ऑब्जेक्ट द्वारा किस तरह के संबंध को परोसा जाना है और इसलिए यूनिट-टेस्ट को अलग करने के लिए उन विशेषताओं का पता लगाना है जिनका मजाक उड़ाया जाना है।


मुझे लगता है कि अब आपको मिल गया है। दुर्भाग्य से, मुझे आपकी टिप्पणी की सूचना नहीं मिली।
स्टीव फ्रीमैन

3

मेरे यहाँ सेवा का मतलब CDPlayer.scheduleToStartAt () था। मीडियाकॉस्ट को यही कहते हैं - सहयोगी को कार्य करने की आवश्यकता है। मीडियाकॉस्ट परीक्षण के तहत आने वाली वस्तु है।

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

क्या उससे मदद हुई?


(इस महान लेख के लेखक :)) मैं इस वाक्य की व्याख्या करना चाहता था: "इससे यह देखना कठिन हो जाता है कि क्या इस रिश्ते का समर्थन करने वाली सेवा कहीं और प्रासंगिक हो सकती है और मुझे अगली बार फिर से काम करना होगा। वर्ग के साथ ”। किस तरह का विश्लेषण? यह पता लगाने का तथ्य कि किस वस्तु का तरीका रिश्ते को लागू करना है क्योंकि यह स्पष्ट रूप से छिपा हुआ है?
मिक 378
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.