2012-11-14 12 views
9

क्या नकली वर्ग बनाने के लिए एक नकली वर्ग बनाने का कोई तरीका है, phpunit के साथ? मैं निर्भरता इंजेक्शन करने का एक तरीका ढूंढ रहा हूं बिना किसी ऑब्जेक्ट को किसी ऑब्जेक्ट को रचनात्मक (या कहीं भी) में काम करने की आवश्यकता हो सकती है। कुछ है कि वापस आ जाएगी इन सभी मामलों के लिए "सही":phpunit के साथ एक नकली कक्षा बनाएँ?

public function testAAAA() 
{ 
    $foo = $this->getMock('foo', array('bar')); 
    var_dump(class_exists('foo', false)); 
    var_dump(method_exists('foo', 'bar')); 
    var_dump(method_exists($foo, 'bar')); 
} 

यह प्रिंट:

bool(true) 
bool(false) 
bool(true) 

यह दर्शाता है कि जब यह सफलतापूर्वक एक नकली 'foo' वर्ग बनाया था यह एक 'बार बाँध नहीं था 'इसके लिए विधि।

मैं phpunit 3.7.5 का उपयोग कर रहा हूँ।

उत्तर

10

मुझे लगता है कि आप नहीं है वास्तव में यह करने के लिए (के रूप में आप PHPUnit के mockbuilder साथ इतने पर कंस्ट्रक्टर्स निष्क्रिय कर सकते हैं और, the docs देखें) चाहते हैं, लेकिन यह सोचते हैं आप चाहते हैं या करने की आवश्यकता है, इस चाल करना चाहिए:

$foo = $this->getMockBuilder('nonexistant') 
     ->setMockClassName('foo') 
     ->setMethods(array('bar')) 
     ->getMock(); 

    var_dump(class_exists('foo', false)); 
    var_dump(method_exists('foo', 'bar')); 
    var_dump(method_exists($foo, 'bar')); 

    $cls = new ReflectionClass('foo'); 
    var_dump($cls->hasMethod('bar')); 

मैं ईमानदारी से इस बात के बारे में निश्चित नहीं हूं कि आपको उपरोक्त अलग-अलग नाम (nonexistant और foo) निर्दिष्ट करने की आवश्यकता क्यों है, लेकिन ऐसा लगता है कि क्लाउड मोनॉक के व्यवहार के साथ ऐसा करना प्रतीत होता है, और setMockClassName उस वर्ग को विस्तारित करने वाली कक्षा उत्पन्न करता है। या कुछ और। यह शायद एक बग/एज-केस के आसपास प्रभावी ढंग से काम कर रहा है - यह लाइब्रेरी का अजीब उपयोग है। आपको getMock अकेले फ़ंक्शन के माध्यम से एक ही चीज़ करने में सक्षम होना चाहिए, यह केवल उलझन में है।

एक तरफ के रूप में, ऐसा लगता है कि आपको शायद php's reflection capabilities से परिचित होना चाहिए। यह वहां पर सबसे शक्तिशाली प्रतिबिंब पुस्तकालय नहीं है, लेकिन यह बहुत अच्छा है। मैंने इसे "मॉडल" लाइब्रेरी के लिए उनके कन्स्ट्रक्टर तर्कों और गुणों के आधार पर कक्षा के लिए आवश्यक और वैकल्पिक फ़ील्ड के बारे में मेटा-सूचना उत्पन्न करने के लिए उपयोग किया है, जहां मेटा-सूचना का उपयोग उन प्रकारों को उत्पन्न करने के लिए किया जाता है जो सही प्रकार के मान स्वीकार करते हैं। यही है, फॉर्म के लिए टाइप किए गए वर्ग के उदाहरणों के बिना टाइप किए गए फॉर्म उत्पन्न करें, और कोड के बेवकूफ मात्रा को हाथ से लिखने के बिना - यह पूरी सुविधा के लिए लगभग 100 लाइनों में है। जाहिर है, मुझे नहीं पता कि आप क्या करने की कोशिश कर रहे हैं, लेकिन आपकी पोस्ट में थोड़ी सी जानकारी से, मुझे लगता है कि यह उस प्रकार की मेटा-चीज़ के करीब नहीं है।

+0

मैं यह नहीं कहूंगा कि मैं यह करना चाहता हूं, लेकिन मुझे यही करना चाहिए। मुझे एक नकली वस्तु उत्पन्न करने में सक्षम होना चाहिए जो परीक्षण के अंदर किए गए कॉल का जवाब देगा, बिना वास्तविक फ़ाइलों को जोड़ने के लिए हजारों फाइलों को बदले बिना। यह getMockBuilder विधि मुझे बंद कर देता है, लेकिन ऐसा लगता है कि phpunit खराब eval कोड उत्पन्न करता है जब इसे नामांकित मॉक क्लास नाम (जिसे मैं उपयोग कर रहा हूं, मुझे मूल पोस्ट में उल्लेख किया जाना चाहिए) के साथ कहा जाता है। –

+0

'get_ockas '(' foo ',' quux \ baz ')'' getMock() 'कॉल के बाद' class_alias' 'पर कॉल जोड़ें, और फिर' quux \ baz' के विरुद्ध परीक्षण करें। उस ने कहा, मुझे लगता है कि आप मूल रूप से उस बिंदु पर हैं जहां आप PHPUnit को पैच करने पर विचार करना चाहते हैं, या फ्लाई पर ऑब्जेक्ट या क्लास में विधियों को जोड़ने की प्रतिबिंब क्लास और प्रतिबिंब ऑब्जेक्ट की क्षमता का उपयोग करना चाहते हैं, और आप किनारे के मामलों को मारने जा रहे हैं। यह ऐसा क्षेत्र नहीं है जहां PHP चमकता है। इसके अलावा, अगर आपने इसे नहीं पढ़ा है, तो आपको * माइकल फेदर द्वारा "विरासत संहिता के साथ प्रभावी ढंग से कार्य करने" की एक प्रति * की आवश्यकता है। – jeremiahd

+0

धन्यवाद। मैं class_alias कोशिश करेंगे। मैं PHPUnit को पैच करने पर भी देख रहा हूं, जो टेम्पलेट को एक eval() में उपयोग करता है। पुस्तक के अनुसार, मालिकों को पढ़ने के लिए मुझे वास्तव में क्या चाहिए। :) –

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