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

Messenger Test Laravel Package

zenstruck/messenger-test

Test helpers and assertions for symfony/messenger. Provides a TestTransport that intercepts and round-trips messages, lets you inspect queued items, assert counts/contents and processing states (acked/rejected), and optionally process queued messages in Kernel/Web tests.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture Fit

  • Enhanced Retry Testing: The new feature (allow enabling/disabling retries manually) directly addresses a gap in Laravel queue testing—retry behavior validation—which is critical for jobs with exponential backoff or failed attempts. This aligns with Laravel’s shouldBeQueued() and failAfterAttempts() patterns but provides finer-grained control.
  • Symfony Messenger Parity: Retry testing was previously limited to Symfony’s native retry middleware. This update bridges the gap for Laravel users relying on spatie/laravel-messenger or custom retry logic.
  • Decoupled Assertions: Retry toggling doesn’t affect core assertion logic (e.g., assertMessageHandled()), maintaining backward compatibility with existing test suites.
  • Laravel Queue Integration: While still Symfony-centric, the feature enables testing of Laravel’s Illuminate\Queue\Retryable jobs when wrapped in Symfony Message interfaces.

Integration Feasibility

  • Retry Middleware Support: If using spatie/laravel-messenger with Symfony’s RetryMiddleware, this feature reduces boilerplate for testing retry scenarios. For native Laravel queues, requires:
    • A RetryMiddleware adapter (e.g., Symfony\Component\Messenger\Middleware\RetryMiddleware configured for Laravel’s retry logic).
    • Or manual retry simulation via MessengerTest::createTransport()->setRetryEnabled(false).
  • Laravel-Specific Retries: Native Laravel retries (e.g., failAfterAttempts) may not map 1:1 to Symfony’s retry system, requiring custom middleware or pre-processing of jobs.
  • Testing Framework: Works seamlessly with PHPUnit; no changes needed for Laravel’s Queue::fake() hybrid setups.
  • Mocking Dependencies: Retry testing may expose dependencies on Laravel’s Queue facade or Bus dispatching, necessitating mock isolation in complex scenarios.

Technical Risk

  • Retry Logic Divergence: Laravel’s retry mechanism (e.g., failAfterAttempts) differs from Symfony’s RetryMiddleware. Adapter complexity increases if testing native Laravel retries without spatie/laravel-messenger.
  • State Management: Manually enabling/disabling retries could lead to flaky tests if not reset between assertions. Requires explicit transport cleanup:
    $transport = MessengerTest::createTransport();
    $transport->setRetryEnabled(false);
    // ... test ...
    $transport->reset(); // Critical for isolation
    
  • Performance Overhead: Retry simulations may slow down tests if not optimized (e.g., testing 10 retries per assertion).
  • Version Skew: Symfony Messenger’s retry middleware behavior may evolve, risking breaking changes in Laravel integrations.

Key Questions

  1. Retry Strategy: Does the app use Symfony’s RetryMiddleware, Laravel’s failAfterAttempts, or a custom solution? This dictates adapter needs.
  2. Queue Driver: Are retries stored in the database, Redis, or another driver? Some drivers (e.g., database) may require custom retry logic.
  3. Test Isolation: How are tests scoped? Shared transports (e.g., Redis) may leak retry states between tests.
  4. Retry Complexity: Are retries combined with delayed jobs, middleware, or exceptions? This affects assertion complexity.
  5. CI/CD Impact: Will retry tests add significant runtime? Consider parallelization or selective test execution.
  6. Long-Term Sync: How will retry logic evolve if migrating between Laravel/Symfony queue systems?

Integration Approach

Stack Fit

  • Primary Use Case: Ideal for Laravel apps using:
    • spatie/laravel-messenger with Symfony’s RetryMiddleware.
    • Custom retry logic wrapped in Symfony Message interfaces.
  • Secondary Use Case: Can supplement Laravel’s Queue::fake() for retry-specific assertions (e.g., verifying failAfterAttempts behavior).
  • Unsupported: Not a drop-in for native Laravel retries without abstraction. Requires:
    • Middleware adapters (e.g., RetryMiddleware for Laravel’s retry logic).
    • Or manual retry simulation in tests.

Migration Path

  1. Assess Retry System:
    • If using Symfony Messenger: Directly leverage setRetryEnabled() in tests.
    • If using Laravel Queues: Build a retry middleware adapter or mock Laravel’s retry logic.
  2. Adapter Implementation (Example):
    // Adapter for Laravel's failAfterAttempts
    use Symfony\Component\Messenger\Middleware\RetryMiddleware;
    
    $retryMiddleware = new RetryMiddleware(
        maxRetries: 3, // Match Laravel's failAfterAttempts
        delay: 1000,   // Match Laravel's retry delay
    );
    $bus = MessengerTest::createBus([$retryMiddleware]);
    
  3. Update Retry Tests:
    • Replace manual retry checks with assertions:
      $transport = MessengerTest::createTransport();
      $transport->setRetryEnabled(false);
      $this->assertMessageNotHandled(MyJob::class); // Fails immediately
      $transport->setRetryEnabled(true);
      $this->assertMessageHandledTimes(MyJob::class, 1); // After retries
      
  4. Hybrid Testing:
    • Combine with Queue::fake() for Laravel-specific features:
      Queue::fake();
      $this->assertNothingReleased(); // Laravel-native check
      

Compatibility

  • Laravel 10/11: Compatible if using spatie/laravel-messenger v2+ or custom retry adapters.
  • Symfony Messenger: Requires v6.3+ for RetryMiddleware features.
  • Queue Drivers: Works with any PSR-15 transport. Database retries may need custom handling.
  • Laravel Extensions: No conflicts with Queue::fake(), but avoid mixing retry states between test suites.

Sequencing

  1. Phase 1: Test basic retry assertions with setRetryEnabled(false) to validate immediate failure paths.
  2. Phase 2: Enable retries and verify handling counts (assertMessageHandledTimes).
  3. Phase 3: Integrate with middleware (e.g., RetryMiddleware) for complex scenarios.
  4. Phase 4: Deprecate manual retry simulations in favor of the package’s API.

Operational Impact

Maintenance

  • Pros:
    • Reduced Boilerplate: Eliminates manual retry simulations (e.g., looping Bus::dispatch() until failure).
    • Explicit Control: Manual retry toggling improves test clarity and isolation.
    • Symfony Alignment: Future-proofs retry testing if adopting Symfony Messenger.
  • Cons:
    • Adapter Complexity: Custom retry logic (e.g., Laravel’s failAfterAttempts) may require ongoing maintenance.
    • State Management: Forgetting to reset retry states can cause flaky tests.
    • Dependency Growth: Adds Symfony Messenger as a dev dependency if not already present.

Support

  • Debugging: Clear error messages for retry-related assertion failures (e.g., "Expected 3 retries, got 0").
  • Documentation: Limited but sufficient for core features. Symfony Messenger docs cover RetryMiddleware in depth.
  • Community: Active GitHub issues for retry-related queries (e.g., #101).
  • Laravel-Specific Gaps: May need custom solutions for Laravel-only retry features (e.g., afterCommit() retries).

Scaling

  • Performance: Retry assertions add minimal overhead; avoid testing excessive retry counts in CI.
  • Parallelization: Safe for PHPUnit parallel tests if transports are isolated per test.
  • Large Test Suites: Scales well, but complex retry scenarios may require selective test execution.

Failure Modes

Risk Impact Mitigation
Retry State Leakage Flaky tests due to shared transport Reset transport between tests.
Adapter Bugs Custom retry logic fails silently Write integration tests for adapters.
Over-Testing Retries Slow CI due to high retry counts Limit retry assertions to critical paths.
Version Conflicts Symfony retry middleware changes Pin versions in composer.json.
Mixed Test Strategies Queue::fake() + MessengerTest conflicts Isolate test suites by queue system.

Ramp-Up

  • Onboarding Time: 2–4 days for teams unfamiliar with Symfony’s retry patterns.
    • Day 1: Install package, test basic retry assertions.
    • Day 2: Build adapters for Laravel-specific retry logic (if needed).
    • Day 3: Migrate complex retry test cases.
    • Day 4: Optimize for CI (e.g., parallelization, selective testing).
  • Training Needs:
    • Symfony RetryMiddleware configuration.
    • Transport state management (reset()).
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.
besmartand-pro/php-quality-config
sentix/ai-chatbot
terminal42/code-quality-tools
codifyo/ts-generator-bundle
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