Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test Laravel Notification sent by Listener?

I have a working code where when a Customer record is created, an event will dispatch and a listener will then send a notification to the Customer's agent.

EventServiceProvider.php

protected $listen = [
        'App\Events\CustomerCreated' => [
            'App\Listeners\TriggerExternalCustomerCreation',
            'App\Listeners\SendNotificationCustomerCreated',
        ],
]

SendNotificationCustomerCreated.php

public function handle(CustomerCreated $event)
    {
        $when = now()->addMinutes(0);
        $event->customer->manager->notify((new CustomerCreatedNotification($event->customer))->delay($when));
    }

Here's my test case:-

public function customer_created_event_dispatch()
    {
        // $this->markTestIncomplete('This test has not been implemented yet.');
        $this->withoutExceptionHandling();
        Event::fake();
        Notification::fake();

        $user = factory(User::class)->states('order management')->create();
        $data = $this->data(['address' => true, 'contact' => true]);

        $response = $this->actingAs($user)->post(route('customers.store'), $data);
        $response->assertSessionHasNoErrors();

        $customers = Customer::all();
        $customer = $customers->first();
        $manager = $customer->manager;

        $this->assertCount(1, $customers);

        Event::assertDispatched(CustomerCreated::class, function ($event) use ($customers) {
            return $event->customer->id === $customers->first()->id;
        });

        Notification::assertSentTo(
            $manager,
            CustomerCreatedNotification::class,
            function ($notification, $channels) use ($customer) {
                return $notification->customer->id === $customer->id;
            }
        );
    }

Initially the listener is queued, but i try removed from queue but error remains.

I can confirmed that the event did dispatch since it passed the Event::assertDispatched. But failed at the last assertion with below errors:-

The expected [App\Notifications\CustomerCreatedNotification] notification was not sent
like image 698
Zaiman Noris Avatar asked Apr 03 '20 15:04

Zaiman Noris


People also ask

What is notify () in Laravel?

Laravel Notify is a package that lets you add custom notifications to your project. A diverse range of notification design is available.


1 Answers

Faking event overwrites ordinary event logic and therefor will not trigger the listeners. This is useful as you sometimes need to block event chains from firing. Faking is also about not caring about side effects, because they are often really hard to test.

Then how do you test that your code work, i prefer to separate Event side effect testing into unit testing. Same approach if i where to test jobs, as the side effects are harder to assert and tests get quite huge if you need to test an endpoint plus a job chain.

Remove the assert notification from your original test. Create an new one in tests/Unit/TestCustomerCreatedEvent or whatever path makes sense.

public function customer_event_listener_tests() {
    // create your data
    $customers = Customer::all();
    $customer = $customers->first();
    $manager = $customer->manager;

    // fake notification only
    Notification::fake();

    $event = new CustomerCreated($customer);
    event($event);

    Notification::assertSentTo(
        $manager,
        CustomerCreatedNotification::class,
        function ($notification, $channels) use ($customer) {
            return $notification->customer->id === $customer->id;
        }
    );
}
like image 64
mrhn Avatar answered Sep 30 '22 17:09

mrhn