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
Laravel Notify is a package that lets you add custom notifications to your project. A diverse range of notification design is available.
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;
}
);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With