3
votes

I am using the auth that came with Laravel. I am testing the page where you put in your email and when you hit the submit button a password reset email will be sent to your email.

The password reset email is sent when I do it manually. But I created this test to make sure the password reset email is sent but it's not working.

There was 1 failure:

1) The expected [Illuminate\Foundation\Auth\ResetPassword] mailable was not queued. Failed asserting that false is true.

I am following this code:

https://github.com/JeffreyWay/council/blob/master/tests/Feature/Auth/RegisterUserTest.php

<?php

namespace Tests\Controllers\Unit;

use Tests\TestCase;
use Illuminate\Support\Facades\Mail;
use Illuminate\Auth\Notifications\ResetPassword;
use Illuminate\Foundation\Testing\RefreshDatabase;

class ResetPasswordEmailTest extends TestCase
{

    use RefreshDatabase;


    public function setUp()
    {
        parent::setUp();
        
        Mail::fake();
    }


    /** @test */
    public function does_send_password_reset_email()
    {
        $user = factory('App\User')->create();

        $this->post(route('password.email'), ['email' => $user->email])
             
        Mail::assertQueued(ResetPassword::class);
    }

}
1

1 Answers

2
votes

You received that error because the password reset email is a Notification and not a Mailable. Note that you must also save the fake user, so that the password reset code can look for it in the database. What worked for me is something like this:

<?php

namespace Tests\Controllers\Unit;

use Tests\TestCase;
use Illuminate\Support\Facades\Notification;
use Illuminate\Auth\Notifications\ResetPassword;
use Illuminate\Foundation\Testing\RefreshDatabase;

class ResetPasswordEmailTest extends TestCase
{
    use RefreshDatabase;

    public function setUp()
    {
        parent::setUp();
        Notification::fake();
    }

    /** @test */
    public function does_send_password_reset_email()
    {
        $user = factory('App\User')->create();
        $user->save();
        $this->post(route('password.email'), ['email' => $user->email])
        Notification::assertSentTo($user, ResetPassword::class);
    }
}

You could also check contents of the email using something like this:

Notification::assertSentTo(
    $user,
    ResetPassword::class, 
    function($notification, $channels) use ($user) {
        $mail = $notification->toMail($user)->build();
        $expected_subject = "Here's your password reset";
        return $mail->subject === $expected_sub;
    }
);