garrcomm/phpunit-helpers

When building unit tests, these helpers can be ... helpful.

v1.0.0 2021-09-04 17:05 UTC

This package is auto-updated.

Last update: 2023-01-09 07:33:06 UTC


README

The name suggests plural, but currently there's one helper: FunctionMock. A second one is in the making though, MysqliMock. Keep in mind, this one is still in development and will always remain a bit limited.

FunctionMock Example

\Garrcomm\PHPUnitHelpers\FunctionMock::mock(
    __NAMESPACE__,
    'mail',
    function ($to, $subject, $body) use (&$verify) {
        $verify = [
            'to' => $to,
            'subject' => $subject,
            'body' => $body,
        ];
        return true;
    }
);

$result = mail('foo@bar.baz', 'subject', 'body');

$this->assertTrue($result);
$this->assertEquals('foo@bar.baz', $verify['to']);
$this->assertEquals('subject', $verify['subject']);
$this->assertEquals('body', $verify['body']);

It's also good to clean up after the test, so in your unit test, add:

class MyTest Extends PHPUnit\Framework\TestCase
{
    public function tearDown(): void
    {
        \Garrcomm\PHPUnitHelpers\FunctionMock::releaseAll();
        parent::tearDown();
    }
}

MysqliMock Example

In your test, you'll need to implement at least two methods to make sure tests are working properly:

use Garrcomm\PHPUnitHelpers\Mysqli\MysqliMock;

class MyTest Extends PHPUnit\Framework\TestCase
{
    public function tearDown(): void
    {
        MysqliMock::reset();
    }

    public static function setUpBeforeClass(): void
    {
        MysqliMock::init();
    }
}

This makes sure all data is cleared after running a test, and makes sure the proper files are loaded to be able to test.

To test if all properties are specified correctly to the constructor, use:

$engine = new mysqli('foo.bar', 'foo', 'bar', 'foobar', 1337);

Garrcomm\PHPUnitHelpers\Mysqli\MysqliMock::assertConstructor(function (
    ?string $hostname,
    ?string $username,
    ?string $password,
    ?string $database,
    ?int $port,
    ?string $socket
) {
    $this->assertEquals('foo.bar', $hostname);
    $this->assertEquals('foo', $username);
    $this->assertEquals('bar', $password);
    $this->assertEquals('foobar', $database);
    $this->assertEquals(1337, $port);
    $this->assertNull($socket);
});

To test of mysqli_report is called correctly, use:

Garrcomm\PHPUnitHelpers\Mysqli\MysqliMock::assertMysqliReport(function(int $flags) {
    $this->assertEquals(3, $flags); // 3 = MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT
});

To mock a query result, and check if a query is called, use:

$fooRequested = false;
Garrcomm\PHPUnitHelpers\Mysqli\MysqliMock::setQueryResponder(
    function (string $query, int $result_mode = MYSQLI_STORE_RESULT) use (&$fooRequested) {
        if ($query == 'SELECT `foo` FROM `bar`' && $result_mode == MYSQLI_STORE_RESULT) {
            $fooRequested = true;
            return \mysqli_result::mockFromArray([['foo' => 'baz']]);
        }
    }
);

performAction();

// Assert if the query is actually executed
$this->assertTrue($fooRequested);