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.
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.spatie/laravel-messenger or custom retry logic.assertMessageHandled()), maintaining backward compatibility with existing test suites.Illuminate\Queue\Retryable jobs when wrapped in Symfony Message interfaces.spatie/laravel-messenger with Symfony’s RetryMiddleware, this feature reduces boilerplate for testing retry scenarios. For native Laravel queues, requires:
RetryMiddleware adapter (e.g., Symfony\Component\Messenger\Middleware\RetryMiddleware configured for Laravel’s retry logic).MessengerTest::createTransport()->setRetryEnabled(false).failAfterAttempts) may not map 1:1 to Symfony’s retry system, requiring custom middleware or pre-processing of jobs.Queue::fake() hybrid setups.Queue facade or Bus dispatching, necessitating mock isolation in complex scenarios.failAfterAttempts) differs from Symfony’s RetryMiddleware. Adapter complexity increases if testing native Laravel retries without spatie/laravel-messenger.$transport = MessengerTest::createTransport();
$transport->setRetryEnabled(false);
// ... test ...
$transport->reset(); // Critical for isolation
RetryMiddleware, Laravel’s failAfterAttempts, or a custom solution? This dictates adapter needs.spatie/laravel-messenger with Symfony’s RetryMiddleware.Message interfaces.Queue::fake() for retry-specific assertions (e.g., verifying failAfterAttempts behavior).RetryMiddleware for Laravel’s retry logic).setRetryEnabled() in tests.// 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]);
$transport = MessengerTest::createTransport();
$transport->setRetryEnabled(false);
$this->assertMessageNotHandled(MyJob::class); // Fails immediately
$transport->setRetryEnabled(true);
$this->assertMessageHandledTimes(MyJob::class, 1); // After retries
Queue::fake() for Laravel-specific features:
Queue::fake();
$this->assertNothingReleased(); // Laravel-native check
spatie/laravel-messenger v2+ or custom retry adapters.RetryMiddleware features.Queue::fake(), but avoid mixing retry states between test suites.setRetryEnabled(false) to validate immediate failure paths.assertMessageHandledTimes).RetryMiddleware) for complex scenarios.Bus::dispatch() until failure).failAfterAttempts) may require ongoing maintenance.RetryMiddleware in depth.afterCommit() retries).| 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. |
RetryMiddleware configuration.reset()).How can I help you explore Laravel packages today?