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 (
// 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
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
// 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)