@pimski I think we’re going to need to see some more code.
How do you test database notifications?
Hi there,
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!
Why? User is standard and the notification is generated with the artisan command "make:notification"
I did change the via method to:
public function via($notifiable)
{
return ['database'];
}
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?
You can access the notification and check the contents:
Notification::assertSentTo(
$user,
ExportFinished::class,
function ($notification, $channels) {
dd($notification); // <-- this is your notification
}
);
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...
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 had exact same issue. If you are not using Notification::fake() you'll get to see your notification once you fresh-load them:
$user->notify(new MyDatabaseNotification());
$user->load('notifications'); // Comment this line and the test will fail.
$this->assertCount(1, $user->notifications);
$this->assertDatabaseCount('notifications', 1);
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.
Please or to participate in this conversation.