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

Callable Fake Laravel Package

timacdonald/callable-fake

A tiny PHP testing utility for faking/invoking callables. CallableFake lets you replace closures or invokable objects, record calls and arguments, assert usage, and return configured values—useful for isolating behavior in PHPUnit/Laravel tests.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture Fit

  • Testing-Focused Utility: The package is a testing-specific tool, not a core framework component. It excels in mocking and assertion of closures/callables, making it ideal for:
    • Service Layer Testing: Validating interactions between services (e.g., Laravel’s App\Services\*).
    • Event/Observer Testing: Capturing closures passed to Event::listen() or Observer::observing().
    • Middleware/Route Closures: Testing request handling logic (e.g., Route::get(..., fn() => ...)).
    • Dependency Injection: Asserting callbacks in container bindings (e.g., bind(fn() => ...)).
  • Laravel Synergy: Works seamlessly with Laravel’s dependency injection, events, and route closures, where callable faking is often needed but under-tested.
  • Limitation: Not a replacement for Laravel’s built-in mocking (e.g., Mockery or PHPUnit mocks). Best used for closure-specific assertions.

Integration Feasibility

  • Low Friction: Composer-installable with zero Laravel-specific configuration. Works alongside existing testing stacks (PHPUnit/Pest).
  • No Core Conflicts: No risk of breaking Laravel’s internals; operates at the testing layer.
  • PHPUnit Dependency: Requires PHPUnit 10+/11/12 (Laravel 9+ uses PHPUnit 9.5+ by default, so compatible with Laravel 10+). For Laravel 8, would need PHPUnit 9.x (but package drops PHPUnit 9.0 support in v1.8.0).
  • PHP Version: Requires PHP 8.2+ (Laravel 10+ uses PHP 8.1+; Laravel 11+ uses PHP 8.2+). No issues for modern Laravel versions.

Technical Risk

  • Minimal: Package is lightweight, battle-tested (45 stars, MIT license), and actively maintained (releases in 2025).
  • Potential Pitfalls:
    • False Positives: If closures are reused across tests, assertions may fail due to shared state. Mitigate with test isolation (e.g., beforeEach resets).
    • Performance: Capturing invocations adds overhead. Use sparingly in large test suites.
    • PHPUnit Version Lock: Dropped PHPUnit 9.0 in v1.8.0; ensure alignment with Laravel’s PHPUnit version.
  • Mitigation: Use in targeted test scenarios (e.g., critical service interactions) rather than globally.

Key Questions

  1. Testing Strategy:
    • Will this replace existing mocking (e.g., Mockery) or supplement it? (Answer: Supplement for closure-specific cases.)
    • Are closures a primary testing pain point in the codebase? (If not, ROI may be low.)
  2. Laravel Version:
    • Is the project on Laravel 10+ (PHP 8.2+)? If not, assess PHPUnit version compatibility.
  3. Adoption Scope:
    • Should this be team-wide or project-specific? (Low adoption = lower risk.)
  4. Alternatives:
    • Could Laravel’s partialMock() or Mockery handle this? (Only if testing objects, not pure closures.)
    • Is there a need for advanced features (e.g., assertCalledIndex) beyond basic mocking?

Integration Approach

Stack Fit

  • PHPUnit/Pest: Native integration with Laravel’s testing stack. Works identically in both.
  • Laravel Services: Ideal for testing:
    • Closure-based bindings (e.g., bindWith(fn() => new Service())).
    • Event listeners (e.g., Event::listen(fn($event) => ...)).
    • Route closures (e.g., Route::get(..., fn() => ...)).
    • Middleware (e.g., Closure::fromCallable([$middleware, 'handle'])).
  • Non-Laravel PHP: Useful for any project using closures/callables in testing (e.g., standalone services).

Migration Path

  1. Assessment Phase:
    • Audit closures in the codebase (e.g., grep -r "fn(" or IDE search).
    • Identify high-value targets (e.g., critical event listeners, service factories).
  2. Pilot Implementation:
    • Replace 1–2 existing tests with CallableFake to validate ROI.
    • Example:
      // Before: Manual assertion
      $listenerCalled = false;
      Event::listen(fn() => $listenerCalled = true);
      // ... trigger event ...
      $this->assertTrue($listenerCalled);
      
      // After: CallableFake
      $fake = new CallableFake();
      Event::listen($fake);
      // ... trigger event ...
      $fake->assertCalled();
      
  3. Full Adoption:
    • Update test templates to include use CallableFake.
    • Add to composer.json dev dependencies:
      "require-dev": {
          "timacdonald/callable-fake": "^1.9"
      }
      
    • No runtime changes needed.

Compatibility

  • Laravel 10+ (PHP 8.2+): Full compatibility.
  • Laravel 9 (PHP 8.1): Use v1.5.0–v1.7.0 (PHP 8.1 support).
  • Laravel 8 (PHP 7.4–8.0): Not recommended (package drops PHP 8.0 support in v1.6.0).
  • PHPUnit 9.5+: Works with Laravel’s default (tested up to PHPUnit 12).
  • Pest Framework: Works identically to PHPUnit (Pest uses PHPUnit under the hood).

Sequencing

  1. Phase 1: Add to composer.json and run tests to ensure no conflicts.
  2. Phase 2: Refactor 1–2 complex closure tests to use CallableFake.
  3. Phase 3: Standardize usage in new tests; gradually migrate legacy tests.
  4. Phase 4: Document patterns (e.g., "Use CallableFake for event listeners").

Operational Impact

Maintenance

  • Low Effort:
    • No runtime dependencies; only affects tests.
    • Updates are non-breaking (MIT license, backward-compatible minor releases).
  • Deprecation Risk:
    • Monitor Laravel’s PHPUnit version (e.g., if Laravel drops PHPUnit 10, check package support).
    • Package is abandonware-risk low (active releases, GitHub activity).

Support

  • Debugging:
    • Clear error messages for failed assertions (e.g., assertCalled()).
    • Stack traces point to test files, not the package.
  • Community:
    • Small but active community (45 stars, recent releases). Issues resolved quickly.
    • GitHub discussions can be used for edge cases.

Scaling

  • Test Suite Growth:
    • Minimal overhead; assertions are fast (no runtime impact).
    • Scales with test coverage (no performance degradation in production).
  • Team Adoption:
    • Easy to learn (simple API: fake, assertCalled, assertCalledWith).
    • Low cognitive load compared to Mockery for closure-specific cases.

Failure Modes

Failure Scenario Impact Mitigation
Closure reused across tests Flaky assertions Reset fakes in beforeEach or use unique instances.
PHPUnit version mismatch Tests fail to run Pin to compatible version in composer.json.
Overuse in performance-critical tests Slower test suite Reserve for high-value assertions.
Package abandonment Unmaintained Monitor GitHub activity; fork if needed.

Ramp-Up

  • Onboarding Time: <1 hour for basic usage.
    • Example workflow:
      1. Install package.
      2. Replace manual closure checks with CallableFake.
      3. Leverage advanced features (e.g., assertCalledWith for argument validation).
  • Training:
    • Add a code snippet template to the team’s testing guide.
    • Example:
      /** @test */
      public function event_listener_is_called()
      {
          $fake = new CallableFake();
          Event::listen($fake);
      
          // Trigger event...
          event(new MyEvent());
      
          $fake->assertCalled();
          $fake->assertCalledWith([$expectedArg]);
      }
      
  • Documentation:
    • Link to the package README and highlight Laravel-specific use cases (e.g., events, routes).
    • Create an internal wiki page for common patterns (e.g., "
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.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky