dg/bypass-finals
DG\BypassFinals lets you bypass PHP’s final classes and methods at runtime so you can mock, extend, or patch code that’s otherwise locked down—useful for testing legacy dependencies. Lightweight, Composer-ready, and works with popular test frameworks.
composer require --dev dg/bypass-finalstests/bootstrap.php), add:
require_once __DIR__ . '/../vendor/autoload.php';
(new \BypassFinals\Loader)->register();
final class — e.g., a framework service like Symfony\Component\HttpFoundation\Request (if declared final) or a vendor utility class — just as you would any regular class:
$mock = $this->createMock(FinalClass::class);
BypassFinals\Loader before class autoloading begins (ideally in phpunit.xml’s bootstrap attribute or at top of tests/bootstrap.php).if (PHP_SAPI === 'cli') or CI-specific flag).$mock = mock(FinalClass::class . '@mock')->makePartial();
bypass-finals doesn’t interfere with coverage collection).memory_limit = -1 for CI if needed).opcache.enable=0) to avoid stale bytecode.final classes and methods are supported, property readonly is only bypassed in PHP 8.1+; earlier versions ignore readonly entirely.Loader::register() ran before the class was loaded — add debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2) in __construct to trace load order.BypassFinals\Rewriter, though the package’s internal API is unstable (no BC guarantees).How can I help you explore Laravel packages today?