A surprising issue with the Auth user and tests

Knowing how this works helps you avoid false failures in your tests

Joel Clermont
Joel Clermont
2023-12-01

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".

Toss a coin in the jar if you found this helpful.
Want a tip like this in your inbox every weekday? Sign up below 👇🏼

Level up your Laravel skills!

Each 2-minute email has real-world advice you can use.