Mocking Final Classes in PhpUnit 9
Mocking final classes in phpUnit 9
This is a copy from Medium: https://medium.com/@gullevek/mocking-final-classes-in-phpunit-9-dee1944ca292
This is an add on to this wonderful article: https://tomasvotruba.com/blog/2019/03/28/how-to-mock-final-classes-in-phpunit/
It describes the basic flow, and also a way how to do this the current version of phpUnit (9.5.20 as of writing)
I want to add help to Point 4 Single Hook file setup.
It is a composer package, but that doesn’t matter for the phpUnit setup part
In my system the folder layout is as follows
/phpunit.xml
: config file for phpUnit/src
: All the content for the composer package/vendor
: the composer files/test
: main test folder with info, etc files/test/phpUnit/
: test files for phpUnit/test/phpUnit/Hook/
: the folder with the phpUnit hooks.
TWO things I had to change to make this work
First: The hook has to be in the BeforeFirstTestHook
and not BeforeTestHook
or the test would run out of memory
<?php
// strip the final name from a to be mocked class
declare(strict_types=1);
namespace test\phpUnit\Hook;
use DG\BypassFinals;
use PHPUnit\Runner\BeforeFirstTestHook;
// only works if it is the FIRST load and not before EACH test
final class BypassFinalHook implements BeforeFirstTestHook
{
public function executeBeforeFirstTest(): void
{
BypassFinals::enable();
}
}
// __END__
Second: the phpunit.xml config file:
<phpunit>
<!-- Below removes final from classes for mock tests -->
<extensions>
<extension class="test\phpUnit\Hook\BypassFinalHook" file="test/phpUnit/Hook/BypassFinalHook.php" />
</extensions>
</phpunit>
With these two changes I could run this successfully and mock final classes in php and phpUnit 9