This is a super quick note to my future self – and you? – about testing object/model properties of Laravel Livewire components.
I’m working on a really simple project and using it as an excuse to practice TDD with Laravel.
I have user-selectable template and my Templates component lets the user select a new template.
My test is pretty simple.
Set up a user and two templates, then assign the first template ID to the user. Note that templates have an owner ($template->owner_id
), but the user also has a chosen template ($user->template_id
):
// Arrange
$user = User::factory()->create();
$template1 = Template::factory()->create([
'owner_id' => $user->id,
]);
$template2 = Template::factory()->create([
'owner_id' => $user->id,
]);
$user->update(['template_id' => $template1->id]);
Then, acting as the user, test the Templates
component, call the setUserTemplate
method then assert that the currentTemplate
property has changed.
// Act
Livewire::actingAs($user)
->test(\App\Http\Livewire\Templates::class)
->call('setUserTemplate', $template2->id)
->assertSet('currentTemplate', $template2);
Before we run the test, I note that the currentTemplate, in the Livewire component, is an Eloquent Model object.
If we run the test we get:
Failed asserting that two objects are equal.
--- Expected
+++ Actual
@@ @@
App\Models\Template Object (
'connection' => 'sqlite'
- 'table' => null
+ 'table' => 'templates'
'primaryKey' => 'id'
'keyType' => 'int'
'incrementing' => true
@@ @@
'withCount' => Array ()
'perPage' => 15
'exists' => true
- 'wasRecentlyCreated' => true
+ 'wasRecentlyCreated' => false
'attributes' => Array (...)
'original' => Array (...)
'changes' => Array ()
Showing that the table
and wasRecentlyCreated
properties of the Template object. The object properties are the same, but it’s a slightly different object behind the scenes.
The problem here is that $template2
is the original template we created using the factory in the test setup. But the currentTemplate
in the component will have been fetched from the database.
The fix for this it to re-fetch $template2
from the database before we compare it. We can do this with $template2->fresh()
// Act
Livewire::actingAs($user)
->test(\App\Http\Livewire\Templates::class)
->call('setUserTemplate', $template2->id)
->assertSet('currentTemplate', $template2->fresh());
This gives us a nice green test:
PHPUnit 9.5.2 by Sebastian Bergmann and contributors.
. 1 / 1 (100%)
Time: 00:00.212, Memory: 32.50 MB
OK (1 test, 3 assertions)
Hooray!