DEV Community

Cover image for Testing Email In Laravel
Nasrul Hazim Bin Mohamad
Nasrul Hazim Bin Mohamad

Posted on

Testing Email In Laravel

Problem Statement

You might come across to the situation where you need to test your email configuration in your Laravel application - in my case, I need to test the:

  • SMTP Connection
  • Send E-mail using Queue
  • Send E-mail not using Queue

I don't want to test my e-mail by having to go through entire process of my application functions.

I'm simply want to tackle above 3 use cases.

Solution

So, let's create an artisan command that be able to send e-mail either using queue or not.

Mail Class

First thing first, let's create a Mail class:

php artisan make:mail DefaultMail
Enter fullscreen mode Exit fullscreen mode

And I have the following class, which I added a bit of customisation on constructor and few other things.

<?php

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Attachment;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Queue\SerializesModels;

class DefaultMail extends Mailable
{
    use Queueable, SerializesModels;

    /**
     * Create a new message instance.
     */
    public function __construct(
        public string $title,
        public $message,
        public ?string $url = null,
        public $attachment = null
    ) {
    }

    /**
     * Get the message envelope.
     */
    public function envelope(): Envelope
    {
        return new Envelope(
            subject: $this->title,
        );
    }

    /**
     * Get the message content definition.
     */
    public function content(): Content
    {
        return new Content(
            view: 'mail.default',
            with: [
                'title' => $this->title,
                'content' => $this->message,
                'url' => $this->url,
            ],
        );
    }

    /**
     * Get the attachments for the message.
     *
     * @return array<int, \Illuminate\Mail\Mailables\Attachment>
     */
    public function attachments(): array
    {
        if (empty($this->attachment) || ! file_exists($this->attachment)) {
            return [];
        }

        return [
            Attachment::fromPath($this->attachment),
        ];
    }
}
Enter fullscreen mode Exit fullscreen mode

The view:

@component('mail::message')
{{ __('Hi') }},

<p style="text-align: justify">
@foreach($message as $msg)
        <span style="text-align: justify">
            {!! $msg !!}
        </span>
@endforeach
</p>

@if(isset($url) && !empty($url) )
    @component('mail::button', ['url' => $url])
    {{ (isset($url_text) && !empty($url_text)) ? $url_text : __('Click here') }}
    @endcomponent
@endif

{{ __('Thanks') }},<br>
{{ config('app.name') }}
@endcomponent
Enter fullscreen mode Exit fullscreen mode

Artisan Command

Next, let's create an artisan command:

php artisan make:command TestSendEmailCommand
Enter fullscreen mode Exit fullscreen mode

Then I have the following in the class:

<?php

namespace App\Console\Commands;

use App\Mail\DefaultMail;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Mail;

class TestSendEmailCommand extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'email:test {email} {--queue= : Type of queue - default, mail, notification}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Send test email';

    /**
     * Execute the console command.
     */
    public function handle()
    {
        $email = new DefaultMail('Test Email', 'This is a test email');

        if ($this->option('queue')) {
            Mail::to($this->argument('email'))
                ->queue(
                    $email->onQueue($this->option('queue'))
                );
        } else {
            Mail::to($this->argument('email'))->send($email);
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Now your artisan command are ready to be test.

Test Sending E-mail

The first test is to send without queue:

php artisan email:test your@email.com 
Enter fullscreen mode Exit fullscreen mode

You should receive the e-mail almost immediately.

Next, sending out e-mail to using queue.

Please make sure you have queue running - either using Horizon or run the queue:work command.

php artisan email:test your@email.com --queue=mail
Enter fullscreen mode Exit fullscreen mode

From queue, it might delayed a little bit, depends on your queue processing.

Summary

With this approach, you can test the mail configuration even in production.

You don't have to go through the application entire process to test the e-mail configuration.

Another note, we can confirm easily with operation / support team in case they saying e-mail didn't get send to users, by testing first the connectivity to the SMTP server.

This helped reduced time to debug the SMTP connectivity.

Credits

Photo by Joanna Kosinska on Unsplash

Top comments (0)