2012-04-12 12 views
14

मैं यूनिट परीक्षण और PHPUnit के लिए नया हूं, लेकिन मैंने हाल ही में डिज़ाइन पैटर्न और पृथक परीक्षणों के बारे में बहुत कुछ पढ़ा है और मैंने एक ऐसे एप्लिकेशन को दोबारा करने का निर्णय लिया है जिस पर मैं काम कर रहा हूं स्थैतिक वर्गों, सिंगलेट्स, हार्डकोडेड निर्भरताओं और वैश्विक दायरे पर परिभाषित कुछ भी छुटकारा पाने के लिए, उम्मीद है कि इसे "टेस्टेबल" बनाना होगा और भविष्य में मैंट में दर्द नहीं होगा, क्योंकि यह एक दीर्घकालिक परियोजना है।नेस्टेड निर्भरताओं और फैक्टरी कक्षाओं के साथ यूनिट परीक्षण करना

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

मुझे प्रश्नों को चित्रित करने दें। मान लीजिए आप निम्नलिखित "विरासत" कोड है:

class House { 
    protected $material; 
    protected $door; 
    protected $knob; 

    public function __construct() { 
     $this->door = new Door(); 
     $this->knob = $this->door->getKnob(); 
     $this->material = "stone"; 

     echo "House material: ".$this->material . PHP_EOL . "<br/>"; 
     echo "Door material: ".$this->door->getMaterial() . PHP_EOL . "<br/>"; 
     echo "Knob material: ".$this->knob->getMaterial() . PHP_EOL . "<br/>"; 
    } 
} 

class Door { 
    protected $material; 
    protected $knob; 

    public function __construct() { 
     $this->knob = new Knob(); 
     $this->material = "wood"; 
    } 

    public function getKnob() { 
     return $this->knob; 
    } 

    public function getMaterial() { 
     return $this->material; 
    } 

} 

class Knob { 
    protected $material; 

    public function __construct() { 
     $this->material = "metal"; 
    } 

    public function getMaterial() { 
     return $this->material; 
    } 
} 

$house = new House(); 

यह (जहाँ तक मेरी समझ जाता है) बुरा इकाई परीक्षण के लिए है, इसलिए हम डि + एक फैक्टरी वर्ग के साथ हार्डकोडेड निर्भरता की जगह:

class House { 
    protected $material; 
    protected $door; 
    protected $knob; 

    public function __construct($door) { 
     $this->door = $door; 
     $this->knob = $this->door->getKnob(); 
     $this->material = "stone"; 

     echo "House material: ".$this->material . PHP_EOL . "<br/>"; 
     echo "Door material: ".$this->door->getMaterial() . PHP_EOL . "<br/>"; 
     echo "Knob material: ".$this->knob->getMaterial() . PHP_EOL . "<br/>"; 
    } 
} 

class Door { 
    protected $material; 
    protected $knob; 

    public function __construct($knob) { 
     $this->knob = $knob; 
     $this->material = "wood"; 
    } 

    public function getKnob() { 
     return $this->knob; 
    } 

    public function getMaterial() { 
     return $this->material; 
    } 

} 

class Knob { 
    protected $material; 

    public function __construct() { 
     $this->material = "metal"; 
    } 

    public function getMaterial() { 
     return $this->material; 
    } 
} 

class HouseFactory { 
    public function create() { 
     $knob = new Knob(); 
     $door = new Door($knob); 
     $house = new House($door); 

     return $house; 
    } 
} 

$houseFactory = new HouseFactory(); 
$house = $houseFactory->create(); 

अब (और फिर, जहां तक ​​मैं समझता हूं) हाउस, दरवाजा और नोब को मैक निर्भरताओं के साथ यूनिट परीक्षण किया जा सकता है। लेकिन:

1) हाउसफैक्टरी के साथ अब क्या होता है?

सिर्फ एक चाहिए:

  • परीक्षण नहीं है, क्योंकि यह किसी भी आवेदन के लायक अभी तक परीक्षण और कारखानों आम तौर पर इस तरह से रहने तर्क नहीं है। मान लें कि यदि घर के लिए स्वतंत्र परीक्षण, दरवाजा & कारखाना पास होना चाहिए तो नोब पास होना चाहिए।
  • किसी भी तरह से कारखाने को रिफैक्टर करें, प्रत्येक उदाहरण को इस तरह से प्राप्त करने के लिए कि कोई भी इन कार्यों को PHPUnit के माध्यम से नकली वस्तुओं को वापस करने के लिए ओवरराइड कर सकता है, बस उस वर्ग में कुछ अतिरिक्त तर्क है जो उपयोग कर सकता है भविष्य में कुछ परीक्षण।

2) क्या परीक्षणों को स्थापित करना संभव है जो कई बार (मजाक नहीं) निर्भरताओं पर भरोसा करते हैं? मैं समझता हूं कि यह तकनीकी रूप से यूनिट परीक्षण नहीं है (शायद एकीकरण परीक्षण?) लेकिन मुझे लगता है कि यह अभी भी PHPUnit का उपयोग कर पूरी तरह से करने योग्य है? ऊपर दिए गए उदाहरण को देखते हुए, मैं एक परीक्षण स्थापित करने में सक्षम होना चाहता हूं जो न केवल अलगाव में हाउस, दरवाजा, नोब और हाउस फैक्ट्री का परीक्षण करता है, बल्कि वास्तविक वस्तुओं के एक दूसरे के साथ बातचीत के परिणाम भी संभवतः उनमें से कुछ के साथ कार्यों का मज़ाक उड़ाया, जैसे डेटा के साथ सौदा। क्या इस तरह के परीक्षणों के लिए PHPUnit एक खराब विकल्प है?

आपके समय के लिए अग्रिम धन्यवाद। मुझे एहसास है कि मैं जो कुछ धारणाएं कर रहा हूं वह सही नहीं हो सकता है, क्योंकि मैं स्पष्ट रूप से इस मामले पर एक विशेषज्ञ नहीं हूं; सुधार स्वागत है और सराहना की है।

उत्तर

4

कारखाना new कीवर्ड जैसा है। क्या आप new कीवर्ड का परीक्षण करते हैं? नहीं, आप परीक्षण करते हैं यदि आप कक्षा बना सकते हैं। लेकिन यह कारखाने के लिए स्वतंत्र है और यूनिट का हिस्सा है जो पहले से ही आपके यूनिट परीक्षणों का हिस्सा है।

2) को एकीकरण परीक्षण कहा जाता है। और आप PHPUnit के साथ भी ऐसा कर सकते हैं।


संपादित - के रूप में वहाँ टिप्पणी में कुछ चर्चा नहीं हुई:

जहां तक ​​इकाई परीक्षण का सवाल है, तो आप अपने कारखाने कि यह करता है कि वह क्या के लिए यूनिट परीक्षण कर सकते हैं के लिए है: एक ठोस प्रकार, एक प्रकार या किसी भी टाइप करें।

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

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

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

+0

फैक्ट्री 'नए' कीवर्ड की तरह नहीं है। इसका परीक्षण किया जा सकता है। 'हाउसफैक्टरी :: बनाना 'क्या करना चाहिए? यह बनाता है और * * हाउस 'देता है। आप परीक्षण कर सकते हैं और परीक्षण करना चाहिए, या तो इकाई परीक्षण या कम से कम एक दावा के साथ। ओपी उदाहरण सरल है, लेकिन यदि आपकी विधि में कोई तर्क है, तो इसका परीक्षण किया जाना चाहिए। – netcoder

+0

इसके अलावा, आप PHP में 'नए' कीवर्ड का परीक्षण नहीं कर सकते हैं (क्योंकि यह ओवरलोड करने योग्य नहीं है), लेकिन आप इसे प्रति उदाहरण C++ में अधिभारित कर सकते हैं, और यदि आप ऐसा करते हैं तो आपको इसका परीक्षण करना चाहिए। – netcoder

+0

'हाउस' के निर्माता के रूप में पहले ही इकाई परीक्षण (टीडीडी के अनुसार) किया गया है, सामान्य रूप से कारखाने विधि का परीक्षण करने की आवश्यकता नहीं है। आप सब कुछ जांच सकते हैं, सवाल यह है कि अगर यह समझ में आता है और वास्तव में आवश्यक है। एकीकरण परीक्षण फैक्ट्री के उपयोग को कवर कर सकते हैं और इसलिए कारखाना नहीं करता है कि कारखाने के लिए क्या किया गया है। – hakre

0

आप इसे विरासत के साथ परीक्षण कर सकते हैं।

बस परीक्षण के लिए नकली हाउस के साथ हाउस का विस्तार करें, और उसके बाद $ सामग्री, $ दरवाजा और $ घुंडी आदि जांचें कि क्या वे परीक्षण के बाद बदल गए हैं या नहीं।

संबंधित मुद्दे