According to Laravel News: Testing Mailable Content in Laravel 8 few additional methods for testing mailable were added to Laravel 8.18.0.
Those are:
1. assertSeeInHtml;
2. assertDontSeeInHtml;
3. assertSeeInText;
4. assertDontSeeInText;
And here is an example of how you can use them:
public function test_mailable_content()
{
$user = User::factory()->create();
$mailable = new UserRegisteredMail($user);
$mailable->assertSeeInText($user->email);
$mailable->assertSeeInHtml('<b>Welcome</b>');
$mailable->assertDontSeeInText($user->password);
$mailable->assertDontSeeInHtml($user->password);
}
My approach for testing mailable is divided into 2 steps:
- make sure email is sent in a feature test;
- unit test mailable;
Let's first look at the feature test. As you can see here, I only make sure that the mail is either sent or queued. As you can see, there is also a callback where you can add an additional condition. If the condition fails, the mail won't' be sent.
// test/Feature/UserRegistrationTest.php
/** @test */
public function email_is_sent()
{
$user = User::factory()->create();
$this->actingAs($user)
->post('register');
Mail::assertQueued(WelcomeMail::class, function ($mail) use ($user) {
// some available methods here are: hasTo, hasBcc, hasCc, hasReplayTo, hasRecipient
return $mail->hasTo($user->email);
});
}
Bellow is the mailable unit test where I assert that the mail:
1. has specific text;
2. has subject;
3. has sender;
// test/Unit/PasswordChangedMailTest.php
<?php
namespace Tests\Unit\Mail;
use App\Mail\PasswordChangedMail;
use Tests\TestCase;
/** @see \App\Mail\PasswordChangedMail */
class PasswordChangedMailTest extends TestCase
{
/** @test */
public function email_contains_password_changed_text()
{
$mail = new PasswordChangedMail();
$mail->assertSeeInText('your password has been changed');
}
/** @test */
public function email_has_a_subject()
{
$mail = new PasswordChangedMail();
$this->assertEquals('Security notification regarding your password', $mail->build()->subject);
}
/** @test */
public function email_has_a_sender()
{
$mail = new PasswordChangedMail();
$this->assertTrue($mail->build()->hasFrom('[email protected]', 'laravellte'));
}
}
If you are interested in how those 4 methods simplified testing mailable, you can check one my commits for an open-source project of mine.
Even though this seems like a small improvement, a pile of small improvements lead to one big one.
And finally, here is the list of all available Mailable methods.