Consider the class Foo:
Code:
<?php
cl Foo
{
public static function dsmthg()
{
return static::hpr();
}
public static function hpr()
{
return 'foo';
}
}
?>
When testing Foo::dsmthg() we want to decouple it from its dependency Foo::hpr(). With PHPUnit 3.5 and PHP 5.3 as well as consistent use of late static binding (using static:: instead of self: the following is possible:
Code:
<?php
cl FooTest extends PHPUnit_Framework_TestCase
{
public function tdsmthg()
{
$cl = $this->getMockClass(
'Foo', /* name of cl to mock */
array('hlpr') /* list of methods to mock */
);
$cl::staticExpects($this->any())
->method('hlpr')
->will($this->returnValue('bar'));
$this->assertEquals(
'bar',
$cl::doSomething()
);
}
}
?>
The new staticExpects() method works similar to the non-static expects() variant.
This approach only works for the stubbing and mocking of static method calls where caller and called are in the same cl. This is because static methods are death to testability.
Note : Unit-Testing needs seams, seams is where we prevent the execution of normal code path and is how we achieve isolation of the class under test. Seams work through polymorphism, we override/implement class/interface and then wire the class under test differently in order to take control of the execution flow. With static methods there is nothing to override. Yes, static methods are easy to call, but if the static method calls another static method there is no way to override the called method dependency.
Bookmarks