Published 2 weeks ago by pimski
How do you test database notifications? The following piece of code works when running in the browser, but gives no results when running in a test case:
auth()->user()->notify(new \App\Notifications\ExportFinished); dd(\DB::table('notifications')->select()->get()); // empty result set in test
Is the test 'mocking' the notification? I'm not calling
Notification::fake(); in my test!
You can mock the notification being sent:
use App\Notifications\ExportFinished; use Illuminate\Support\Facades\Notification; ... Notification::fake(); $user->notify(new ExportFinished); Notification::assertSentTo($user, ExportFinished::class);
Should work just the same regardless of delivery method (email, database).
Hi @Nash thanks for the reply. I already managed to test there 'is' a notification. However, my next step was to check the contents of the notification (as stored in the database). And this is what isn't working.
The posted code does work when I check it in the browser. So my guess there is some test-magic going on that prevents the notification from actually being saved in the database. How can one actually save notifications in the database in tests?
Aha. So the way to check a notification is by using the Notification facade? And not by checking the notifications relationship on the user? Even if you don't use Notification::fake() in your test...
@pimski No, this is related to my previous example using
Notification::fake(). I just pointed out that you can access the notification and check the contents just fine. You don't need to manually query the DB for that.
@Nash I understood that, and got my test working, so thanks for that! I was just wondering if code like this is never possible:
$user->notify(new MyDatabaseNotification()); $this->assertCount(1, $user->notifications);
To me this feels more natural. But maybe I just need to change my test-mindset
I haven't tried it your way so I can't really say. Maybe the notifications are going to your real db instead of your testing db?
Remember that notifications can also be sent by email, in which case you probably don't want them to be sent for real. Using
Notification::fake() makes sure that doesn't happen in case you or someone else changes the delivery method later on.