This tip continues the theme started yesterday related to Eloquent strictness checks
After turning it on, I had some tests fail related to preventAccessingMissingAttributes
. This feature makes sure an error is thrown if you try to access a property that doesn't exist on a model, instead of just silently returning null
.
In my case, I knew those properties existed on the model, but my tests were failing. The issue has to do with how the actingAs
method in tests influences with the $request->user
available inside application code.
Consider this test snippet:
$user = User::factory()->create(['xyz' => 'abc']);
$this->actingAs($user);
$this->get('/'); // other assertions below here
In this test example, let's say my route has form request validation which uses $request->user
. That User
model will only have the properties defined in my factory, plus the ones passed in to the create()
method.
If the User
model has other properties which are not used in this particular factory call, they will not exist in that test request, and preventAccessingMissingAttributes
will throw an error.
The reason is that, unlike a normal request, a test request isn't hydrating the User
model from the database. It's using what was created inside the test and bound into the request in memory.
The fix was easy, and just required an extra line or two of test setup, but it caught me by surprise.
Here to help,
Joel
P.S. Eloquent strictness is one easy way to get more confident with your code. Ash has published a helpful guide with many more tips to make your Laravel apps "battle ready".