Skip to content

Instantly share code, notes, and snippets.

@vedmant
Created May 18, 2017 12:14
Show Gist options
  • Save vedmant/57a908908457e160f5cab39cc7a93d5b to your computer and use it in GitHub Desktop.
Save vedmant/57a908908457e160f5cab39cc7a93d5b to your computer and use it in GitHub Desktop.
Helper for testing emails with Laravel
<?php
namespace Tests;
use Mail;
use Swift_Events_EventListener;
use Swift_Events_SendEvent;
use Swift_Mime_Message;
/**
* Trait TracksEmails
*
* @package Tests
*/
trait TracksEmails
{
/**
* Delivered emails.
*
* @var array
*/
protected $emails = [];
/**
* Register a listener for new emails.
*
* @before
*/
public function setUpMailTracking()
{
Mail::getSwiftMailer()
->registerPlugin(new TestingMailEventListener($this));
}
/**
* Assert that at least one email was sent.
*
* @return $this
*/
protected function seeEmailWasSent()
{
$this->assertNotEmpty(
$this->emails, 'No emails have been sent.'
);
return $this;
}
/**
* Assert that no emails were sent.
*
* @return $this
*/
protected function seeEmailWasNotSent()
{
$this->assertEmpty(
$this->emails, 'Did not expect any emails to have been sent.'
);
return $this;
}
/**
* Assert that the given number of emails were sent.
*
* @param integer $count
* @return $this
*/
protected function seeEmailsSent($count)
{
$emailsSent = count($this->emails);
$this->assertCount(
$count, $this->emails,
"Expected $count emails to have been sent, but $emailsSent were."
);
return $this;
}
/**
* Assert that the last email's body equals the given text.
*
* @param string $body
* @param Swift_Mime_Message $message
* @return $this
*/
protected function seeEmailEquals($body, Swift_Mime_Message $message = null)
{
$this->assertEquals(
$body, $this->getEmail($message)->getBody(),
"No email with the provided body was sent."
);
return $this;
}
/**
* Assert that the last email's body contains the given text.
*
* @param string $excerpt
* @param Swift_Mime_Message $message
* @return $this
*/
protected function seeEmailContains($excerpt, Swift_Mime_Message $message = null)
{
$this->assertContains(
$excerpt, $this->getEmail($message)->getBody(),
"No email containing the provided body was found."
);
return $this;
}
/**
* Assert that the last email's subject matches the given string.
*
* @param string $subject
* @param Swift_Mime_Message $message
* @return $this
*/
protected function seeEmailSubject($subject, Swift_Mime_Message $message = null)
{
$this->assertEquals(
$subject, $this->getEmail($message)->getSubject(),
"No email with a subject of $subject was found."
);
return $this;
}
/**
* Assert that the last email was sent to the given recipient.
*
* @param string $recipient
* @param Swift_Mime_Message $message
* @return $this
*/
protected function seeEmailTo($recipient, Swift_Mime_Message $message = null)
{
$this->assertArrayHasKey(
$recipient, (array) $this->getEmail($message)->getTo(),
"No email was sent to $recipient."
);
return $this;
}
/**
* Assert that the last email was delivered by the given address.
*
* @param string $sender
* @param Swift_Mime_Message $message
* @return $this
*/
protected function seeEmailFrom($sender, Swift_Mime_Message $message = null)
{
$this->assertArrayHasKey(
$sender, (array) $this->getEmail($message)->getFrom(),
"No email was sent from $sender."
);
return $this;
}
/**
* Store a new swift message.
*
* @param Swift_Mime_Message $email
*/
public function addEmail(Swift_Mime_Message $email)
{
$this->emails[] = $email;
}
/**
* Retrieve the appropriate swift message.
*
* @param Swift_Mime_Message $message
* @return mixed
*/
protected function getEmail(Swift_Mime_Message $message = null)
{
$this->seeEmailWasSent();
return $message ?: $this->lastEmail();
}
/**
* Retrieve the mostly recently sent swift message.
*/
protected function lastEmail()
{
return end($this->emails);
}
}
/**
* Class TestingMailEventListener
*
* @package Tests
*/
class TestingMailEventListener implements Swift_Events_EventListener
{
protected $test;
/**
* TestingMailEventListener constructor.
*
* @param $test
*/
public function __construct($test)
{
$this->test = $test;
}
/**
* Before email sent
*
* @param Swift_Events_SendEvent $event
*/
public function beforeSendPerformed(Swift_Events_SendEvent $event)
{
$this->test->addEmail($event->getMessage());
}
}
@gabrielpeixoto
Copy link

Not working on Laravel 5.8 =(

@vedmant
Copy link
Author

vedmant commented Aug 2, 2019

@gabrielpeixoto You don't need that in Laravel 5.8, it has built in mock for emails https://laravel.com/docs/5.8/mocking#mail-fake

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment