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
Mailer Test

Mailer Test Laravel Package

zenstruck/mailer-test

Opinionated helpers to test emails sent with symfony/mailer. Use InteractsWithMailer in KernelTestCase/WebTestCase for fluent assertions like assertNoEmailSent, assertSentEmailCount, and inspect messages with TestEmail (subject, recipients, body, attachments).

View on GitHub
Deep Wiki
Context7

Alternative, opinionated helpers for testing emails sent with symfony/mailer.

Frequently asked questions about Mailer Test
How does zenstruck/mailer-test compare to Laravel’s native Mail::fake() for testing emails?
zenstruck/mailer-test offers advanced assertions like file attachments, metadata, and Symfony-specific headers, which Laravel’s Mail::fake() lacks. It’s ideal for hybrid Laravel/Symfony apps or when you need granular control over email content validation. For pure Laravel apps, Mail::fake() is simpler and more integrated.
Can I use zenstruck/mailer-test with Laravel without Symfony’s FrameworkBundle?
Yes, but you’ll need to adapt the InteractsWithMailer trait to work with Laravel’s TestCase. The package assumes Symfony’s KernelTestCase/WebTestCase, so a wrapper trait is required. Example: Extend Laravel’s TestCase and override getMailer() to return Laravel’s Symfony Mailer instance.
What Laravel versions support zenstruck/mailer-test?
Laravel 9+ is required due to PHP 8+ and Symfony 5.4+ dependencies. For Laravel 8, ensure you’re using symfony/mailer ^6.4 and spatie/laravel-mail (if applicable). Test compatibility by checking your Symfony Mailer bridge’s version requirements.
How do I reset email state between test cases to avoid persistence issues?
Call `$this->mailer()->reset()` in your test’s setUp() or tearDown() methods. Unlike Mail::fake(), zenstruck/mailer-test persists emails between tests by default. Skipping resets can cause memory leaks or incorrect assertions in subsequent tests.
Does zenstruck/mailer-test work with Laravel’s queue system for delayed emails?
No, it directly tests Symfony’s MailerInterface, not Laravel’s queue system. For queued emails, flush the queue manually (e.g., $this->artisan('queue:flush')) before assertions or use Mail::fake() for unit tests where queuing is irrelevant.
Are there alternatives to zenstruck/mailer-test for Laravel email testing?
Yes: Laravel’s Mail::fake() (built-in), spatie/laravel-mail’s MailAssertions, or mocking Symfony’s MailerInterface directly. Choose zenstruck/mailer-test only if you need Symfony-specific assertions (e.g., attachments, metadata) or hybrid app testing.
How do I debug failed email assertions in zenstruck/mailer-test?
Use `$this->mailer()->sentEmails()->dump()` to inspect all sent emails. For specific failures, chain assertions with ->assertSubject(), ->assertFrom(), etc., to isolate issues. Unlike Mail::fake(), there’s no direct Laravel debugging tool, so manual inspection is key.
Will zenstruck/mailer-test slow down my CI/CD pipeline?
Potentially, as it requires Symfony’s profiler for some features (e.g., zenstruck/browser integration). Disable unused profiler features in CI or use Mail::fake() for faster unit tests. Benchmark your pipeline to identify bottlenecks.
Can I customize TestEmail assertions for domain-specific validation (e.g., Postmark tags)?
Yes, extend the TestEmail class to add custom assertions. For example, override assertHasTag() to validate Postmark-specific metadata. This is useful for Laravel apps using third-party email services with unique requirements.
How do I migrate from Mail::fake() to zenstruck/mailer-test in an existing Laravel project?
Start by replacing 1–2 critical email tests to validate parity. Update composer.json to include symfony/mailer and zenstruck/mailer-test, then adapt your test cases to use InteractsWithMailer. Use Mail::fake() for unit tests and zenstruck/mailer-test for integration tests requiring advanced assertions.
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.
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver