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

Mock Final Classes Laravel Package

nunomaduro/mock-final-classes

Dev-only helper that automatically enables mocking of final classes and methods in PHP tests. Works with PHPUnit, Pest, and ParaTest by removing final keywords on the fly via dg/bypass-finals—install with Composer and it just works.

View on GitHub
Deep Wiki
Context7

Getting Started

  1. Install via Composer: composer require --dev nunomaduro/mock-final-classes
  2. No configuration needed — the package auto-registers via PHPUnit’s bootstrap process (and now Pest and ParaTest) when installed. Simply run phpunit, pest, or paratest as usual.
  3. First use case: Mock a final class from an external SDK (e.g., Stripe, AWS SDK, or Laravel’s own Application class pre-9.0).
    // Works seamlessly in PHPUnit, Pest, and ParaTest
    $sdkClient = $this->createMock(FinalSdkClient::class);
    $sdkClient->method('send')->willReturn('mocked response');
    

    💡 It works out of the box in all supported frameworks — no need to extend custom TestCase, add annotations, or adjust test runners.

Implementation Patterns

  • Replace createMock() or getMockBuilder() normally: The package intercepts PHP’s final enforcement transparently. Use existing mocking workflows ($this->createMock(), mock(), Prophecy, Mockery if manually integrated).
  • Ideal for integration tests: Isolate external HTTP services or legacy libraries that use final for API stability — now also in parallel test suites via ParaTest.
  • Combine with test doubles:
    // Mocking a final command from a third-party library
    $command = $this->createMock(FinalCommand::class);
    $command->method('execute')->willReturn(['status' => 'ok']);
    
    $service = new MyService($command);
    $this->assertEquals(['status' => 'ok'], $service->run());
    
  • Use with Data Providers: Generate mocks per test case to avoid cross-test pollution — works seamlessly in both serial and parallel execution.
  • With Mockery: Though not first-class, you can manually load the trait:
    use NunoMaduro\MockFinalClasses\MockFinalClassesTrait;
    
    Mockery::mock(FinalClass::class . '[method]', null, true)
        ->shouldAllowMockingProtectedMethods()
        ->viaMockFinalClasses();
    
  • Pest-first workflows: Use the mock() helper as usual — no extra steps required:
    $mock = mock(FinalSdkClient::class);
    $mock->allowMockingProtectedMethods();
    $mock->shouldReceive('send')->andReturn('mocked');
    

Gotchas and Tips

  • Only affects test execution: Production code remains untouched — final is still enforced outside test context.
  • Known limitations:
    • Does not support mocking final methods inside final classes (only class-level final).
    • May conflict with other extensions that alter class loading or use reflection heavily (e.g., Xdebug with strict settings).
    • ParaTest workers are now supported, but ensure the package is installed globally in dev dependencies per worker environment (no autoloading across worker processes).
  • Debugging: If mocking fails silently:
    1. Ensure nunomaduro/mock-final-classes appears after phpunit/phpunit (or pestphp/pest) in composer.json’s require-dev.
    2. For ParaTest, verify the package is available in the worker’s autoloader (e.g., via --bootstrap or phpunit.xml inclusion).
    3. Run tests with --stop-on-failure and inspect for ReflectionException or TypeError.
  • Performance: Minimal overhead — only active during mock creation, but avoid excessive mock generation in tight loops (especially in ParaTest, where initialization cost multiplies per process).
  • Future-proofing: Since PHP 8.2+, use #[\AllowDynamicProperties] and readonly alongside final — this package does not bypass readonly (only final), so test against such classes may still fail.
  • Extension tip: Internally uses ReflectionClass::setExportOptions() (PHP ≥8.1) — ensure your test environment matches PHP ≥8.1 to leverage all features.
  • New in v1.2.0: Full support for Pest and ParaTest — you no longer need workarounds or manual bootstrap hooks to enable final-class mocking across parallel or Pest-based test suites.
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