When using the Mail facade in Laravel it is not so easy to test the output of the parsed mail template. Like http://stackoverflow.com/questions/31120567/unittesting-laravel-5-mail-using-mock I received the error Method Mockery_0__vendor_Swift_Mailer::getTransport() does not exist on this mock object. I ended up in listening to the mailer.sending event:

public function testRegistrationMailIsSend_afterSubmittingForm()
{
// flag for closure has been called
$mailerAssertionHasBeenCalled = false;

// receive every Event::fire method and pass the reference from the outer scope into the closure
Event::shouldReceive('fire')->andReturnUsing(function($event, $params) use (&$mailerAssertionHasBeenCalled) {
// filter only the mailer.sending event
if ($event != 'mailer.sending') {
return;
}

// reference will be modified
$mailerAssertionHasBeenCalled = true;
// Swift_Message; Illuminate\Mail\Mailer::sendSwiftMessage
$msg = $params[0];

$this->assertEquals('Verify your e-mail account', $msg->getSubject());
$recipients = $msg->getTo();

$this->assertTrue(array_key_exists('my@domain.com', $recipients));
$verificationKey = Registration::first()->verification_key;

// assert registration key is present in parsed template
$this->assertContains('/registration/verify-email?key=' . $verificationKey, $msg->getBody());
});

// visit our registration controller
$this->visit('/registration')
->submitForm('Register', ['email' => 'my@domain.com'])
->see('Mail has been sent');

// make sure that our closure has been called
$this->assertTrue($mailerAssertionHasBeenCalled);
}
Categories: Laravel