Besides I have added the following Queue Connection for testing purposes:
QUEUE_CONNECTION=sync
QUEUE_DRIVER=sync
Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.
Hi Folks!
I would like to write a PHPUnit test where I would like to proof if the verification email was send after register.
My goal is to override the email template used to send for the verification email therefore I have made the following changes:
App\User public function sendEmailVerificationNotification()
{
$this->notify((new VerificationEMail));
}
App\Notifications\User\VerificationEMail<?php
namespace App\Notifications\User;
use Illuminate\Auth\Notifications\VerifyEmail;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
class VerificationEMail extends VerifyEmail implements ShouldQueue
{
use Queueable;
/**
* Create a new notification instance.
*
* @return void
*/
public function __construct()
{
//
}
/**
* Get the notification's delivery channels.
*
* @param mixed $notifiable
* @return array
*/
public function via($notifiable)
{
return ['mail'];
}
/**
* Get the mail representation of the notification.
*
* @param mixed $notifiable
* @return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
$verificationUrl = $this->verificationUrl($notifiable);
return (new MailMessage)
->subject(__('verify.mail.subject'))
->from(__('verify.mail.from'))
->markdown(
'mail.user.verification', compact(
'verificationUrl'
)
);
}
/**
* Get the array representation of the notification.
*
* @param mixed $notifiable
* @return array
*/
public function toArray($notifiable)
{
return [
//
];
}
}
My test case looks like this:
/** @test */
public function it_queues_a_verification_notification_email()
{
$user = factory(User::class)
->make()
->makeVisible(['password']);
Mail::fake();
Mail::assertNothingSent();
$this->put(
route('auth.register.store'),
$user->toArray()
);
Mail::assertQueued(VerifyEmail::class);
}
I begin to make a user in order to have a valid user data. Than I send (put) the user to the register route which is the default register action from Laravel:
public function register(SignupRequest $request)
{
event(new Registered($user = $this->create($request->all())));
$request->flash('flash_success', __('register.success'));
$this->guard()->login($user);
if ($request->wantsJson()) {
return response()
->json([
'message' => 'success',
'success' => true,
]);
}
return $this->registered($request, $user)
?: redirect()->back()->with([
'message', 'success',
'success' => true,
]);
}
It works in produciton but not in testing. Why does my test not work? What should I do in order to test if the verification email was send to the queue and finally to the user?
Thank you in advance and best regards Alexander (sirthxalot)
@sti3bas Thank you for your help! I have found out what the problem was:
The assertion sent to used a user that doesn't exists. I had to fetch the genereated user and than do the assertion - so the assertion end up like this:
public function it_queues_a_verification_notification_email()
{
$user = factory(User::class)
->make()
->makeVisible(['password']);
Notification::fake();
Notification::assertNothingSent();
$this->put(
route('auth.register.store'),
$user->toArray()
);
$user = User::firstWhere('email', $user->email);
Notification::assertSentTo($user, VerificationEMail::class);
Notification::assertTimesSent(1, VerificationEMail::class);
}
Using the $this->expectsEvents(\Illuminate\Auth\Events\Registered::class); was not a good idea since it fakes the events so after this line the event will never triggered.
Stupid mistake I am sorry for that.
Please or to participate in this conversation.