Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Bypass Finals Laravel Package

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.

View on GitHub
Deep Wiki
Context7

Getting Started

  1. Install via Composer: composer require --dev dg/bypass-finals
  2. In your test bootstrap file (e.g., tests/bootstrap.php), add:
    require_once __DIR__ . '/../vendor/autoload.php';
    (new \BypassFinals\Loader)->register();
    
  3. First use case: Write a test that mocks a 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);
    

Implementation Patterns

  • Bootstrap early: Register BypassFinals\Loader before class autoloading begins (ideally in phpunit.xml’s bootstrap attribute or at top of tests/bootstrap.php).
  • Selective coverage: Only run tests with bypass enabled in CI/test environments; never in production (e.g., wrap in if (PHP_SAPI === 'cli') or CI-specific flag).
  • Mixed mocking tools: Use alongside PHPUnit, Mockery, or Pest — e.g., with Mockery:
    $mock = mock(FinalClass::class . '@mock')->makePartial();
    
  • Integration with code coverage: Bypassed code remains testable in coverage reports (verify via Xdebug/PCOV + bypass-finals doesn’t interfere with coverage collection).

Gotchas and Tips

  • Runtime overhead: Parsing and rewriting bytecode adds minimal overhead — acceptable in tests/CI but avoid in production.
  • Memory limits: Heavy use with large codebases may increase memory usage (set memory_limit = -1 for CI if needed).
  • Extensions compatibility: Conflicts possible with opcache or JIT; disable opcache in test environment (opcache.enable=0) to avoid stale bytecode.
  • Final methods only: While final classes and methods are supported, property readonly is only bypassed in PHP 8.1+; earlier versions ignore readonly entirely.
  • Debugging: If mocks fail unexpectedly, verify Loader::register() ran before the class was loaded — add debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2) in __construct to trace load order.
  • Extension point: You can customize rewriter behavior by extending BypassFinals\Rewriter, though the package’s internal API is unstable (no BC guarantees).
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport