php-mock/php-mock-phpunit

Mock built-in PHP functions (e.g. time()) with PHPUnit. This package relies on PHP's namespace fallback policy. No further extension is needed.


Keywords
testing, phpunit, BDD, TDD, test, mock, stub, test double, function, builtin-functions, php, php-mock
License
WTFPL

Documentation

.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