Search code examples
laravelemailtestingphpunitphpmailer

Laravel implement assertSentFrom specific address Mailable Testing


Trying to get to grips with Mocking and test cases, I want to test that a Mailable TestMail is sent from company@company.com, the documentation provides hasTo, hasCc, and hasBcc but doesn't look like it uses something like hasFrom. Is there any solutions to this?

https://laravel.com/docs/9.x/mocking#mail-fake

public function testEmailAlwaysFrom()
{

    Mail::fake();

    Mail::to('foo@bar.com')->send(new TestMail);

    Mail::assertSent(TestMail::class, function ($mail) {
        return assertEquals('company@company.com', $mail->getFrom());
        // return $mail->hasTo($user->email) &&
        //     $mail->hasCc('...') &&
        //     $mail->hasBcc('...');
    });

}

Solution

  • MailFake doesn't provide hasFrom method in the class and therefore will return false.

    The workaround below however doesn't work when using the environmental variable MAIL_FROM_ADDRESS, ->from() has to be called within build().

    A couple of GitHub issues have been reported suggesting a workaround below:

    https://github.com/laravel/framework/issues/20056 https://github.com/laravel/framework/issues/20059

    public function testEmailAlwaysFrom()
    {
    
        Mail::fake();
    
        Mail::to('foo@bar.com')
            ->send(new TestMail);
    
        Mail::assertSent(TestMail::class, function ($mail) {
    
            $mail->build(); // <-- workaround
        
            return $mail->hasTo('foo@bar.com') and
                $mail->hasFrom('company@company.com');
            
        });
            
    }