2012-06-07 10 views
8

को छोड़कर सभी विधियों का नकल करें, मैं एक PHPUnit परीक्षण लिख रहा हूं, जहां मुझे कुछ निर्भरता का नकल करने की आवश्यकता है, लेकिन मुझे अभी भी पहले के रूप में काम करने के लिए कुछ तरीकों की आवश्यकता है। यानी, मेरे पास है:PHPUnit: कुछ

class Dependency { 
// some stuff not important for the test 
    public function thisOneINeed() { 
    /// complex code 
    } 
// some more stuff 
} 

तो मैं कुछ इस तरह कर रहा था:

// prepare mock object 
$dep = $this->getMockBuilder('Dependency')->disableOriginalConstructor()->getMock(); 
// mock out some other method that should return fixed value 
$dep->expects($this->any())->method("shouldGetTrue")->will($this->returnValue(true)); 
// run test code, it will use thisOneINeed() and shouldGetTrue() 
$result = $testSubject->runSomeCode($dep); 
$this->assertEquals($expected, $result); 

और सब कुछ विधि thisOneINeed() को छोड़कर ठीक है बाहर मज़ाक उड़ाया जाता है तो मैं चलाने के लिए जटिल कोड और नहीं मिलता है मैं ठीक से काम करने के लिए इसे runSomeCode() के लिए चलाने की आवश्यकता है। thisOneINeed() में वह कोड किसी भी अन्य विधियों को कॉल नहीं करता है, लेकिन उचित परीक्षण के लिए इसकी आवश्यकता है और यह निश्चित मूल्य वापस नहीं करता है, इसलिए मैं केवल स्थाई रिटर्न वैल्यू() नहीं डाल सकता। और AFAIK PHPunit में returnValue() जैसी कोई विधि नहीं है जो "कॉल पेरेंट" कहती है। इसमें returnCallback() है लेकिन इसे कहने का कोई तरीका नहीं है "जहां तक ​​मैं देख सकता था" इसे "मूल वर्ग के लिए इस विधि को कॉल करें"।

मैं Dependency में सभी विधियों की सूची बना सकते हैं, यह से thisOneINeed को हटा दें और जब नकली निर्माण setMethods() को इसे पारित, लेकिन मुझे लगता है कि दृष्टिकोण पसंद नहीं है, kludgy लग रहा है।

मैं भी ऐसा कर सकता है:

class MockDependency extends Dependency 
{ 
    // do not let the mock kill thisOneINeed function 
    final public function thisOneINeed() 
    { 
     return parent::thisOneINeed(); 
    } 
} 

और फिर MockDependency का उपयोग नकली वस्तु का निर्माण करने के लिए है, और इस पर भी काम करता है, लेकिन मैं मैन्युअल रूप से नकली क्या करने वाले पसंद नहीं है।

तो क्या ऐसा करने का एक बेहतर तरीका है?

उत्तर

9

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

मैंने व्यक्तिगत रूप से इसे कई मामलों में उपयोगी पाया है ताकि प्रतिबिंब क्लास का उप-वर्ग हो सके कि जब मुझे उनकी आवश्यकता हो, तो मैं विधियों को जोड़ सकता हूं।

class MyReflectionClass extends ReflectionClass 
{ 
    public function getAllMethodNamesExcept(array $excluded) 
    { 
     $methods = array_diff(
      get_class_methods($this->name), 
      $excluded 
     ); 
     return $methods; 
    } 
} 

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