spatie/laravel-mailable-test
Adds an Artisan command to quickly send any Laravel Mailable to a chosen email address for preview and debugging, without filling out forms or running full app flows. Constructor parameters are detected and passed automatically.
Installation:
composer require spatie/laravel-mailable-test --dev
Add the service provider to config/app.php under providers (if not auto-discovered):
Spatie\MailableTest\MailableTestServiceProvider::class,
First Use Case:
Test a OrderConfirmation mailer with a recipient:
php artisan mail:send-test "OrderConfirmation" recipient@example.com
Order model) if passed as CLI arguments:
php artisan mail:send-test "OrderConfirmation" recipient@example.com 1
Where to Look First:
php artisan mail:send-test --help for usage details.config/mailable-test.php (if published) for customizations like default mailers or queues.Basic Testing: Send a mailer with default arguments:
php artisan mail:send-test "InvoiceMailable" user@example.com
Constructor Arguments: Pass arguments directly to the mailer’s constructor:
php artisan mail:send-test "ResetPasswordMailable" user@example.com 123
config/mailable-test.php:
'argument_mappings' => [
'ResetPasswordMailable' => [
'user_id' => 0, // 0-based index for CLI args
],
],
Queueable Mailers: Test queueable mailers by dispatching them directly:
php artisan mail:send-test "DelayedNewsletterMailable" user@example.com --queue
MAIL_MAILER in .env for testing).Custom Mailers: Extend the command for custom logic (e.g., mocking services):
// app/Console/Commands/CustomMailTest.php
use Spatie\MailableTest\MailTestCommand;
class CustomMailTest extends MailTestCommand {
protected $signature = 'mail:custom-test {mailable} {recipient} {--queue}';
protected $description = 'Custom mail test command';
public function handle() {
$this->sendTestMail($this->argument('mailable'), $this->argument('recipient'), $this->option('queue'));
}
}
Integration with Tests: Use in PHPUnit tests to verify mail content:
use Spatie\MailableTest\MailTest;
public function test_invoice_mail() {
MailTest::sendTestMail('InvoiceMailable', 'user@example.com', 1);
$this->assertCount(1, Mail::to('user@example.com')->hasBeenSent());
}
Debugging Emails:
Use --preview to render the email without sending:
php artisan mail:send-test "WelcomeMailable" user@example.com --preview
config/mailable-test.php).Batch Testing: Loop through recipients in a script:
for email in $(cat emails.txt); do
php artisan mail:send-test "NewsletterMailable" "$email"
done
CI/CD Pipelines: Add to deployment scripts to validate emails before release:
# .github/workflows/test.yml
- name: Test Mailables
run: php artisan mail:send-test "CriticalAlertMailable" ci@example.com
Argument Mismatch:
argument_mappings in config or ensure argument order matches:
// For: public function __construct(User $user, string $token)
php artisan mail:send-test "ResetPasswordMailable" user@example.com 1 abc123
Queue Configuration:
MAIL_MAILER is not set to a queue driver (e.g., queue:async)..env for testing:
MAIL_MAILER=queue
QUEUE_CONNECTION=sync
Preview Mode Quirks:
--preview may not render assets (CSS/JS) if not configured for local development.Namespace Conflicts:
App\Mailers\OrderConfirmation vs. App\Mail\OrderConfirmation).php artisan mail:send-test "App\Mailers\OrderConfirmation" user@example.com
Environment-Specific Behavior:
testing vs. local environments (e.g., assets, queues)..env.testing or override config per environment.Log Output: Enable verbose logging for the command:
php artisan mail:send-test "Mailable" user@example.com --verbose
Mail Facade Inspection:
Use Laravel’s Mail::pretend() in tests to inspect sent mail:
Mail::pretend();
MailTest::sendTestMail('Mailable', 'user@example.com');
$mail = Mail::assertSentTo('user@example.com')->first();
Swift Mailer Debugging: For Swift Mailer errors, check Laravel logs or enable Swift’s debug mode:
// config/mail.php
'debug' => env('MAIL_DEBUG', false),
Custom Recipients: Use environment variables for dynamic recipients:
php artisan mail:send-test "Mailable" "${TEST_EMAIL}" --queue
TEST_EMAIL=test@example.com
Template Testing: Test Blade templates by passing dynamic data:
php artisan mail:send-test "TemplateMailable" user@example.com --data='{"key":"value"}'
Performance: Disable queues for local testing to avoid delays:
php artisan mail:send-test "Mailable" user@example.com --queue=sync
Extension Points:
Spatie\MailableTest\MailTestCommand to add pre/post-send logic.Mail::fake() to assert mail content in tests without sending:
Mail::fake();
MailTest::sendTestMail('Mailable', 'user@example.com');
Mail::assertSent(Mailable::class);
Configuration: Publish the config for customization:
php artisan vendor:publish --provider="Spatie\MailableTest\MailableTestServiceProvider" --tag="config"
'default_mailer' => 'ses',
'default_queue' => 'mail',
How can I help you explore Laravel packages today?