2013-02-09 10 views
7

क्या आप phpunit में मैक क्लास के संरक्षित गुण प्राप्त करने के लिए कॉलबैक के अंदर $ $ का उपयोग कर सकते हैं? या इसे प्राप्त करने का कोई और तरीका है? अगर आप मज़ाक उड़ाया वस्तुओं इंजेक्शन लगाने के बारे में सोचते हैं

$mock = $this->getMock('A', array('foo')); 
$mock->expects($this->any())->method('foo')->will(
    $this->returnCallback(function() { 
     return $this->bar; 
})); 

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

class A { 
    protected $bar = "bar"; 

    public function foo() { 
    $b = new B(); 
    return $b->fizz($this->bar); 
    } 
} 

class B { 
    public function fizz ($buzz) { 
    return $buzz; 
    } 
} 

लेकिन कहें कि कक्षा बी कुछ खराब करता है और मैं इसे नकली के साथ बदलना चाहता हूं।

$mockB = $this->getMock('B'); 
// (...) - and probably mock other things 
$mockA = $this->getMock('A', array('foo')); 
$mockA->expects($this->any())->method('foo')->will(
    $this->returnCallback(function() use ($mockB) { 
     return $mockB->fizz($this->bar); 
})); 

क्या यह किसी भी तरह से प्राप्त करने योग्य है?

PHP Fatal error: Using $this when not in object context in (...) 

use कीवर्ड का उपयोग करते हुए मैं माता पिता के दायरे से $ mockA वारिस कर सकते हैं::

किसी भी आश्चर्य के बिना बेशक

, वर्तमान में, अगर मैं फिर ऊपर की तरह यह कर मैं त्रुटि मिलती है

$mockB = $this->getMock('B'); 
// (...) - and probably mock other things 
$mockA = $this->getMock('A', array('foo')); 
$mockA->expects($this->any())->method('foo')->will(
    $this->returnCallback(function() use ($mockA, $mockB) { 
     return $mockB->fizz($mockA->bar); 
})); 

लेकिन इस तरह मैं बार को सार्वजनिक रूप से एक्सेस करने का प्रयास करूंगा और मुझे मिल जाएगा:

PHP Fatal error: Cannot access protected property (...) 

उत्तर

0

एस इन्स पीएचपी 5.4 आप बंद में $this उपयोग कर सकते हैं, लेकिन आप वस्तु से इस कॉलबैक, कि इन संरक्षित गुण होता है वापस जाने के लिए है:

class A { 
    protected $bar = "bar"; 

    public function foo() { 
     $b = new B(); 
     return $b->fizz($this->bar); 
    } 

    public function getCallback(B $b) { 
     return function() use($b) { 
      return $b->fizz($this->bar); 
     }; 
    } 
} 

class B { 
    public function fizz ($buzz) { 
     return $buzz; 
    } 
} 

$mockA = new A; 
$mockB = new B; 

$callBack = $mockA->getCallback($mockB); 
var_dump($callBack() === $mockA->foo()); 

हालांकि, अगर आप संरक्षित गुण का मान प्राप्त करने की आवश्यकता है, तो आप सार्वजनिक गेटर परिभाषित करना चाहिए इसके लिए। इस तरह, परीक्षण PHP 5.3

+0

हाँ मैं जानता हूँ कि मैं सार्वजनिक गेटर परिभाषित लेकिन कहते हैं कि यह एक बाहरी पुस्तकालय है या आप बस इसे सुरक्षित रखने के लिए करना चाहते हैं कर सकते हैं। पूरा प्रश्न इस बात के बारे में है कि दिए गए मामले में कक्षा के संरक्षित गुण कैसे प्राप्त करें। तो PHP 5.3 के लिए उत्तर अभी भी नहीं है, आप ऐसा नहीं कर सकते हैं। PHP 5.4 के लिए, बढ़िया आप इसका उपयोग कर सकते हैं! यह बहुत बड़ा कदम है! लेकिन फिर भी मुझे कक्षा को बदलने की जरूरत है जिसे मैं बदलना नहीं चाहता हूं। क्या आप कम से कम कक्षा बना सकते हैं जो 'getCallback (B $ b)' जोड़ने के लिए ए को बढ़ाता है? इसे जांचने की आवश्यकता है। इस सुविधा का उल्लेख करने के लिए –

1

जैसा कि डीएच-नल-निवासी द्वारा इंगित किया गया है, PHP 5.4 में आप इसे बंद करने के भीतर $ $ का उपयोग कर सकते हैं जैसे कि आप सामान्य रूप से विधि में काम करते हैं।

5.3 में आप ऐसा करके इस व्यवहार की नकल कर सकते हैं:

public function getCallback(B $b) { 
    $self = $this; 
    return function() use($b, $self) { 
     return $b->fizz($self->bar); 
    }; 
} 
7

के रूप में अन्य उत्तर ने बताया है, $this पीएचपी 5.4 के बाद से क्लोजर में इस्तेमाल किया जा सकता है। एक कम ज्ञात तथ्य यह है कि आप मनमानी वस्तुओं को बंद करने के लिए बाध्य कर सकते हैं और वास्तव में उनके निजी गुणों को इस तरह सुलभ बना सकते हैं। आपको जिस विधि की आवश्यकता है वह bindTo() है, जो विभिन्न संदर्भों के साथ नया बंद देता है।

$cb = function() { 
    return $this->bar; 
}; 
$cb = $cb->bindTo($mockA); 

या अधिक सटीक, अपने उदाहरण है कि ऐसा दिखाई देगा:

$mockB = $this->getMock('B'); 
// (...) - and probably mock other things 
$mockA = $this->getMock('A', array('foo')); 
$fooCallback = function() use (&$mockB) { 
    return $mockB->fizz($this->bar); 
}; 
$mockA->expects($this->any())->method('foo')->will(
    $this->returnCallback($fooCallback->bindTo($mockA))); 
+1

+1। PHPUnit PHP 5 के उपयोग को भी प्रोत्साहित करता है।4, तो यह स्विच बनाने शुरू करने के लिए एक अच्छा समय हो सकता है। (स्वयं को भी ध्यान दें ... :)) – qrazi

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

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