Skip to content

Mock built-in PHP functions (e.g. time() or rand()) in PHPUnit.

License

Notifications You must be signed in to change notification settings

php-mock/php-mock-phpunit

Folders and files

NameName
Last commit message
Last commit date

Latest commit

1a9855f · Apr 4, 2025
Apr 4, 2025
Mar 19, 2025
Mar 22, 2018
Mar 12, 2025
Feb 8, 2020
Apr 1, 2015
Jan 25, 2022
Mar 19, 2025
Mar 19, 2025
Apr 1, 2015

Repository files navigation

.github/workflows/tests.yml

Mock PHP built-in functions with PHPUnit

This package integrates the function mock library PHP-Mock with PHPUnit.

Installation

Use Composer:

composer require --dev php-mock/php-mock-phpunit

Usage

PHP-Mock integrates with the trait PHPMock into your PHPUnit test case. This trait extends the framework by the method getFunctionMock(). With this method you can build a mock in the way you are used to build a PHPUnit mock:

namespace foo;

class BuiltinTest extends \PHPUnit\Framework\TestCase
{

    use \phpmock\phpunit\PHPMock;

    public function testTime()
    {
        $time = $this->getFunctionMock(__NAMESPACE__, "time");
        $time->expects($this->once())->willReturn(3);

        $this->assertEquals(3, time());
    }

    public function testExec()
    {
        $exec = $this->getFunctionMock(__NAMESPACE__, "exec");
        $exec->expects($this->once())->willReturnCallback(
            function ($command, &$output, &$return_var) {
                $this->assertEquals("foo", $command);
                $output = ["failure"];
                $return_var = 1;
            }
        );

        exec("foo", $output, $return_var);
        $this->assertEquals(["failure"], $output);
        $this->assertEquals(1, $return_var);
    }
}

There's no need to disable the mocked function. The PHPUnit integration does that for you.

Restrictions

This library comes with the same restrictions as the underlying php-mock:

  • Only unqualified function calls in a namespace context can be mocked. E.g. a call for time() in the namespace foo is mockable, a call for \time() is not.

  • The mock has to be defined before the first call to the unqualified function in the tested class. This is documented in Bug #68541. In most cases you can ignore this restriction. But if you happen to run into this issue you can call PHPMock::defineFunctionMock() before that first call (e.g. with @beforeClass). This would define a side effectless namespaced function. Another effective approach is running your test in an isolated process (e.g. with @runInSeparateProcess).

License and authors

This project is free and under the WTFPL. Responsable for this project is Markus Malkusch markus@malkusch.de.

Donations

If you like this project and feel generous donate a few Bitcoins here: 1335STSwu9hST4vcMRppEPgENMHD2r1REK