4

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);
    }

}
Community
  • 1
  • 1

1 Answers1

3

You received that error because the password reset email is a Notification and not a Mailable. What works for me is something like this:

<?php

namespace Tests\Controllers\Unit;

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

class ResetPasswordEmailTest extends TestCase
{
    use RefreshDatabase;

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

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

You can also verify the contents of the email using a callback as the third argument. The callback receives the notification and an array of channels, and should return true or false to pass or fail the assertion. For example:

$expected_subject = "Here's your password reset";
Notification::assertSentTo(
    $user,
    ResetPassword::class, 
    fn ($n, $c) => $n->toMail($user)->build()->subject === $expected_sub;
);
miken32
  • 42,008
  • 16
  • 111
  • 154
  • Thank you so much you saved my life. I looked everywhere trying to find the Mailable that was sent for password reset, and ended up not finding anything. Your method worked beautifully, thanks! – dulerong Feb 26 '21 at 06:07