mercredi 18 septembre 2019

Laravel Notifaction Mailable not beein sent in Test

I'am using a notification to send a mail to all users when the notification gets Triggered.

This works fine in manual "browsing the website" usage (submit a POST to the ContactFormController) but in my tests the mail facade claims that no mail gets sent.

Controller:

<?php

namespace App\Http\Controllers;

use App\Notifications\ContactRequestNotification;
use App\User;
use Illuminate\Http\Request;
use Notification;

class ContactController extends Controller
{
    public function create(Request $request)
    {
        $validateData = $request->validate([
            'name' => 'required',
            'email' => 'required|email',
            'message' => 'required'
        ]);

        Notification::send(User::all(), new ContactRequestNotification($validateData));

        return $validateData;
    }
}


Notification:

<?php

namespace App\Notifications;

use App\Mail\ContactMail;
use Illuminate\Mail\Mailable;
use Illuminate\Notifications\Notification;

class ContactRequestNotification extends Notification
{
    /**
     * @var array
     */
    private $contactData;

    /**
     * Create a new notification instance.
     *
     * @return void
     */
    public function __construct($contactData)
    {
        $this->contactData = $contactData;
    }

    /**
     * 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 Mailable
     */
    public function toMail($notifiable)
    {
        return (new ContactMail($this->contactData['name'], $this->contactData['email'], $this->contactData['message']))->to($notifiable->email);
    }

    /**
     * Get the array representation of the notification.
     *
     * @param mixed $notifiable
     * @return array
     */
    public function toArray($notifiable)
    {
        return $this->contactData;
    }
}


Mailable:

<?php

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;

class ContactMail extends Mailable
{
    use Queueable, SerializesModels;

    /** @var string */
    public $name;

    /** @var string */
    public $email;

    /** @var string */
    public $message;

    /**
     * Create a new message instance.
     *
     * @return void
     */
    public function __construct($name, $email, $message)
    {
        $this->name = $name;
        $this->email = $email;
        $this->message = $message;
    }

    /**
     * Build the message.
     *
     * @return $this
     */
    public function build()
    {
        return $this->markdown('emails.contact')
            ->from(env('MAIL_FROM'))
            ->subject('New contact request');
    }
}


Test:

<?php

namespace Tests\Feature;

use App\Mail\ContactMail;
use App\Notifications\ContactRequestNotification;
use App\User;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Support\Facades\Mail;
use Notification;
use Tests\TestCase;

class ContactFormTest extends TestCase
{
    use DatabaseMigrations;

    /** @test */
    public function a_notification_gets_created_when_the_contact_form_is_used()
    {
        Notification::fake();

        $user = factory(User::class)->create();

        $response = $this->post('/contact', [
            'name' => 'John Doe',
            'email' => 'email@email.com',
            'message' => 'This is a test message'
        ]);

        $response->assertStatus(200);

        Notification::assertSentTo($user, ContactRequestNotification::class);
    }

    /** @test */
    public function a_mail_is_send_when_the_contact_form_is_used()
    {
        $this->withExceptionHandling();

        factory(User::class)->create();

        Mail::fake();

        Mail::assertNothingSent();

        $data = [
            'name' => 'John Doe',
            'email' => 'email@email.com',
            'message' => 'This is a test message'
        ];

        $response = $this->post('/contact', $data);

        $response->assertStatus(200);

        Mail::assertSent(ContactMail::class, 1);
    }
}


The "a_notification_gets_created_when_the_contact_form_is_used" test runs without any problems but the second test case results in:

/usr/bin/php /home/vendor/phpunit/phpunit/phpunit --configuration /home/phpunit.xml --filter "/(::a_mail_is_send_when_the_contact_form_is_used)( .*)?$/" Tests\Feature\ContactFormTest /home/tests/Feature/ContactFormTest.php --teamcity
PHPUnit 8.3.4 by Sebastian Bergmann and contributors.


The expected [App\Mail\ContactMail] mailable was sent 0 times instead of 1 times.
Failed asserting that false is true.


When performing the same tasks in the browser a mail gets sent to the user.

Any tips on what i am missing here? An internet search revealed that some other people had this problem but neither found a solution (or that I am not capable of performing the correct search)

Thanks!

Aucun commentaire:

Enregistrer un commentaire