Skip to content

[7.x] Implement mail factory on mailfake#31752

Closed
xHeinrich wants to merge 2 commits into
laravel:7.xfrom
xHeinrich:7.x
Closed

[7.x] Implement mail factory on mailfake#31752
xHeinrich wants to merge 2 commits into
laravel:7.xfrom
xHeinrich:7.x

Conversation

@xHeinrich

@xHeinrich xHeinrich commented Mar 5, 2020

Copy link
Copy Markdown
Contributor

Implement mail factory on mailfake, for some reason without this when calling Mail::fake() on a request where a notification email is sent the following error is thrown:

TypeError : Argument 1 passed to Illuminate\Notifications\Channels\MailChannel::__construct() must implement interface Illuminate\Contracts\Mail\Factory, instance of Illuminate\Support\Testing\Fakes\MailFake given

Notification email example:

$user->notify(new UserCreatedNotification($user));
<?php

namespace App\Notifications;

use App\EmailSettings;
use Illuminate\Auth\Passwords\DatabaseTokenRepository;
use Illuminate\Auth\Passwords\PasswordBroker;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Database\ConnectionInterface;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;

class UserCreatedNotification extends Notification
{
    use Queueable;

    public $user;

    public $token;

    /**
     * Create a new notification instance.
     *
     * @param $user
     */
    public function __construct($user)
    {
        $this->user = $user;

        /** @var PasswordBroker $broker */
        $broker = app('auth.password.broker');
        $this->token = $broker->createToken($user);
    }

    /**
     * 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 MailMessage
     */
    public function toMail($notifiable)
    {
        $greeting = EmailSettings::where('notification_type', get_class($this))->first()->greeting;
        return (new MailMessage())
            ->greeting($greeting)
            ->line(
                sprintf(
                    'Welcome %s, you have been added as a user to %s',
                    $this->user->first_name,
                    config('app.name')
                )
            )
            ->action('Login Here', route('password.reset', ['token' => $this->token]));
    }
}

@taylorotwell

Copy link
Copy Markdown
Member

But MailFake doesn't have a factory method?

@xHeinrich

Copy link
Copy Markdown
Contributor Author

image

@driesvints

Copy link
Copy Markdown
Member

@xHeinrich the mail fake cannot be used here because the notification doesn't sends a Mailable. It sends a SimpleMessage instance. You need to use the Notification fake.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants