I have a simple LIvewire component consisting of a form to create a new User, and it work, i can tell since i've been asked to write tests after the project already reached staging.
The Livewire component use a new User
instance (non presisted, i.e. user->exists
is false
) to store inserted data before persisting it, and the user
model hides the password attribute trough the protected $hidden
array.
Now, i can sucesfully create new users trough the form page in my local environment, but when it comes to testing, it gives me error.
The test
Livewire::test(
FormComponent::class,
)
->set('user.name', 'user name')
->set('user.email', '[email protected]')
->set('user.password', 'password')
->assertSet('user.name', 'user name')
->assertSet('user.email', '[email protected]')
->assertSet('user.password', 'password');
The error
Failed asserting that null matches expected 'password'.
What i find out
Setting my compoment user instance trough the form page goes fine because livewire recognize it as a model
, so do something like user->password = 'password'
, while when setting it from the test with set()
it access its property with the access operator as it is an array, i.e.: user['password] = 'password'
.
Commenting out the password entry in the $hidden
array made the test pass.
This will explain the difference in the property setting.
Conclusion
Since the $hidden
array is meant to hide model properties in its array/json representation it should not interfere with automated tests, moreover when using Livewire own methods, so to me this looks like a LIvewire Bug.
Help
Does anyone have aver encountered this bug?
Update#1
I've opened an issue on Livewire github page for this.
You have diagnosed this pretty well. When Livewire serializes the User model,
password
is not included because it is in the$hidden
array. Even though the User model has not been persisted yet, serialization is the same.I would guess that your input fields all use the
defer
modifier, which is why your fields are working in the browser; however, when you callset()
in the test, it simulates a Livewire request, so the$hidden
attributes are being wiped.An alternate assertion for testing the password is my recommendation here. Try asserting that the created user can login with the selected password.