Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Stubbing a method called by a class' constructor

Tags:

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);   } } 
like image 398
jontyc Avatar asked Apr 05 '11 03:04

jontyc


1 Answers

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'); ... 
like image 145
David Harkness Avatar answered Oct 10 '22 01:10

David Harkness