I am developing a Laravel application. I am doing unit test. But having a bit of a problem of testing the email being sent.
My test code is something like this.
public function test_something()
{
Mail::fake();
//other test code
Mail::assertSent(\App\Mail\ApplicationCreatedEmail::class, 1);
}
In the actual implementation. I am sending the notification as the email. The notification was sent in the event.
I have a notifiable model like this.
class User extends Authenticatable implements MustVerifyEmail
{
use Notifiable,
//other code
}
I send the notification in the event like this.
class ApplicationCreated
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public $application;
public function __construct($application)
{
$this->application = $application;
}
}
Then I have a listener for that event like this.
class ApplicationCreatedListener
{
public function handle(ApplicationCreated $event)
{
$event->application->user->notify(
new ApplicationCreatedNotification($event->application)
);
}
}
As you can see, in the listener, I am sending notification (ApplicationCreatedNotification). This is the definition of ApplicationCreatedNotification.
class ApplicationCreatedNotification extends Notification
{
use Queueable;
public $application;
public function __construct(Application $application)
{
$this->application = $application;
}
public function via($notifiable)
{
return ['mail'];
}
public function toMail($notifiable)
{
return new ApplicationCreatedEmail($notifiable)->to($notifiable->email);
}
public function toArray($notifiable)
{
return [
];
}
}
As you can see, the notification is sent as an email (Mailable).
This is my mailable class (ApplicationCreatedEmail).
class ApplicationCreatedEmail extends Mailable implements ShouldQueue
{
use SerializesModels, Queueable;
public $application;
public function __construct($application)
{
$this->application= $application;
$this->subject('Application created');
}
public function build()
{
return $this->markdown('emails.application_created', []);
}
}
Then in the code, I trigger the event like this in the controller.
event(new ApplicationCreated($application));
If you go back to the test, as you can see, I am trying to test if the email is being sent. But it is failing because the email was not sent. But instead, if I test if the notification is sent like this.
public function test_something()
{
Notification::fake();
//other code
Notification::assertSentTo($application->user, ApplicationCreatedNotification::class);
}
It works. Testing the notification works. Testing the email being sent is failing. But if I test the email being sent, the email class is triggered as well because I logged the variables using dd() helper. It even runs the build function of mailable with any errors. Just the test is failing. What is the possible error? How can I fix it?