How does one stub a method in PHPUnit that is called by the class under test's constructor? The simple code below for example won't work because by the time I declare the stubbed method, the stub object has already been created and my method called, unstubbed.
Class to test:
class ClassA { private $dog; private $formatted; public function __construct($param1) { $this->dog = $param1; $this->getResultFromRemoteServer(); } // Would normally be private, made public for stubbing public getResultFromRemoteServer() { $this->formatted = file_get_contents('http://whatever.com/index.php?'.$this->dog); } public getFormatted() { return ("The dog is a ".$this->formatted); } }
Test code:
class ClassATest extends PHPUnit_Framework_TestCase { public function testPoodle() { $stub = $this->getMockBuilder('ClassA') ->setMethods(array('getResultFromRemoteServer')) ->setConstructorArgs(array('dog52')) ->getMock(); $stub->expects($this->any()) ->method('getResultFromRemoteServer') ->will($this->returnValue('Poodle')); $expected = 'This dog is a Poodle'; $actual = $stub->getFormatted(); $this->assertEquals($expected, $actual); } }
Use disableOriginalConstructor()
so that getMock()
won't call the constructor. The name is a bit misleading because calling that method ends up passing false
for $callOriginalConstructor
. This allows you to set expectations on the returned mock before calling the constructor manually.
$stub = $this->getMockBuilder('ClassA') ->setMethods(array('getResultFromRemoteServer')) ->disableOriginalConstructor() ->getMock(); $stub->expects($this->any()) ->method('getResultFromRemoteServer') ->will($this->returnValue('Poodle')); $stub->__construct('dog52'); ...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With