Mocking global PHP functions in phpunit
20 Jul 2016 in Programming, PHP, phpunit
In order to mock global php functions like date()
, rand()
, etc, I developed
a simple solution utilizing phpunit's getMock()
method.
For example, assuming you are trying to mock the date()
function, replace the
occurences of the function in your class with a call to a new protected method
that calls this function and returns the result.
So, the following snippet:
class ExampleClass {
public function foo() {
$date = date('Y-m-d H:i:s');
// do something
// ...
return $date;
}
}
becomes:
class ExampleClass {
public function foo() {
$date = $this->date();
// do something
// ...
return $date;
}
protected function date() {
return date('Y-m-d H:i:s');
}
}
Then, in your tests, instead of creating the actual class, create it via
phpunit's getMock()
method like this:
// The first parameter is the class name and the second the methods to mock
// Consult phpunit's manual for extra parameters like constructor arguments
$exampleClassInstance = $this->getMock(ExampleClass::class, ["date"]);
Finally, write your tests and set the return value of ExampleClass::date()
on each test:
class ExampleClassTest extends PHPUnit_Framework_TestCase {
protected $sut;
protected function setUp() {
$this->sut = $this->getMock(ExampleClass::class, ["date"]);
}
public function testFoo() {
$expected = "2010-01-01 00:00:00";
$this->sut->expects($this->any())
->willReturn($expected)
->method("date");
$actual = $this->sut->foo();
$this->assertEquals($expected, $actual);
}
}
This will test the actual class, except mock methods, with code coverage.
Alternative solutions: