Taking the following code snippet:
<?phpclass Example{public function methodCall(){Logger::logMessage('message', 4, new Exception());return true;}}?>
A static method call, which needs to be stubbed out, is made from within the methodCall() function. Mike Lively suggests refactoring under these circumstances, so that calls to static methods that are external to the class are encapsulated within a new class method.
Refactoring, then yields something like this:
<?phpclass Example{public function methodCall(){$this->logMessage('message', 4, new Exception());return true;}public function logMessage($message, $priority, Exception $exception){Logger::logMessage($message, $priority, $exception);}}?>
A unit test which stubs out the logMessage() function can then be created:
<?phprequire_once 'PHPUnit/Framework/TestCase.php';require_once 'Example.php';require_once 'Logger.php';class ExampleTest extends PHPUnit_Framework_TestCase{public function testMethodCall(){$example = $this->getMock('Example', array('logMessage'));$example->expects($this->any())->method('logMessage');$this->assertEquals($example->methodCall(), true);}}?>
At this point, everything works as expected.
However, problems arise if an equivalent process is followed for static method calls. For instance, if the Example class methods are static:
<?phpclass Example{public static function methodCall(){self::logMessage('message', 4, new Exception());return true;}public static function logMessage($message, $priority, Exception $exception){Logger::logMessage($message, $priority, $exception);}}?>
The unit test now ignores the stubbed method and calls the original class method. Furthermore, direct calls to the stubbed method throw the following error "Fatal error: Using $this when not in object context in......."
These issues have been documented, but were not easy to find and another ticket on the PHPUnit site indicates that stubbing static methods works as expected. As can be seen when reading through the posts on ticket 139, it appears that support for stubbing static methods was withdrawn sometime between Jun 2007 and Feb 2008, with no indication that this will be made available.