2

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?

4

0 回答 0