Mocking PHP functions in unit tests Mocking PHP functions in unit tests php php

Mocking PHP functions in unit tests


Not in an automated way. What you can do, is to write your code in a way such that external dependencies are wrapped in objects that are passed in from the outside. In your production environment you'll just wire up the real adapters, but during testing, you can wire it to stubs or mocks.

If you really insist, you can use the runkit extension which changes php's programming model so that you can redefine classes and functions at runtime. This is an external and nonstandard extensions however, so keept that in mind. The defacto standard is a manual approach as I described above.


Here is an interesting article that writes about mocking global php functions. The author proposes a very creative solution to 'Mock' (kind off) the global php functions by overwriting the methods inside the namespace of the SUT (service under test).

Here code from an example in the blog post where the time function is mocked:

<?phpnamespace My\Namespace;use PHPUnit_Framework_TestCase;/** * Override time() in current namespace for testing * * @return int */function time(){    return SomeClassTest::$now ?: \time();}class SomeClassTest extends PHPUnit_Framework_TestCase{    /**     * @var int $now Timestamp that will be returned by time()     */    public static $now;    /**     * @var SomeClass $someClass Test subject     */    private $someClass;    /**     * Create test subject before test     */    protected function setUp()    {        parent::setUp();        $this->someClass = new SomeClass;    }    /**     * Reset custom time after test     */    protected function tearDown()    {        self::$now = null;    }    /*     * Test cases     */    public function testOneHourAgoFromNoon()    {        self::$now = strtotime('12:00');        $this->assertEquals('11:00', $this->someClass->oneHourAgo());    }    public function testOneHourAgoFromMidnight()    {        self::$now = strtotime('0:00');        $this->assertEquals('23:00', $this->someClass->oneHourAgo());    }}

Not sure if this is a good way to do it but it surely works well and I think it is worth mentioning here. Could be some food for a discussion...


There is a PHPUnit extension that uses runkit internally, and is capable to use invocation matchers, parameter constraints and everything a mocked object can do.

https://github.com/tcz/phpunit-mockfunction