PHPUnit Mock Objects and Static Methods PHPUnit Mock Objects and Static Methods php php

PHPUnit Mock Objects and Static Methods


Sebastian Bergmann, the author of PHPUnit, recently had a blog post about Stubbing and Mocking Static Methods. With PHPUnit 3.5 and PHP 5.3 as well as consistent use of late static binding, you can do

$class::staticExpects($this->any())      ->method('helper')      ->will($this->returnValue('bar'));

Update: staticExpects is deprecated as of PHPUnit 3.8 and will be removed completely with later versions.


There is now the AspectMock library to help with this:

https://github.com/Codeception/AspectMock

$this->assertEquals('users', UserModel::tableName());   $userModel = test::double('UserModel', ['tableName' => 'my_users']);$this->assertEquals('my_users', UserModel::tableName());$userModel->verifyInvoked('tableName'); 


I would make a new class in the unit test namespace that extends the Model_User and test that. Here's an example:

Original class:

class Model_User extends Doctrine_Record{    public static function create($userData)    {        $newUser = new self();        $newUser->fromArray($userData);        $newUser->save();    }}

Mock Class to call in unit test(s):

use \Model_Userclass Mock_Model_User extends Model_User{    /** \PHPUnit\Framework\TestCase */    public static $test;    // This class inherits all the original classes functions.    // However, you can override the methods and use the $test property    // to perform some assertions.}

In your unit test:

use Module_User;use PHPUnit\Framework\TestCase;class Model_UserTest extends TestCase{    function testCanInitialize()    {           $userDataFixture = []; // Made an assumption user data would be an array.        $sut = new Mock_Model_User::create($userDataFixture); // calls the parent ::create method, so the real thing.        $sut::test = $this; // This is just here to show possibilities.        $this->assertInstanceOf(Model_User::class, $sut);    }}