Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

larslehmann's avatar

Auth facade not working in (PHPUnit|Pest) tests.

Hello everyone.

I have a global scope inside one of my models which ensures that only entries for the currently authenticated user are shown:

protected static function booted(): void
    {
        if (Auth::hasUser()) {
            static::addGlobalScope('user', function (Builder $builder) {
                $builder->where('user_id', Auth::id());
            });
        }
    }

The scope is working fine outside of tests.

Now I wanted to write a simple test which checks whether the scope is working. (The test is not there to prove that the scope is working but rather it ensures that the scope is present and not accidentally removed.):

it('only shows projects for the authenticated user', function () {
    $user = UserFactory::new()->create();
    ProjectFactory::new()->user($user)->create();
    ProjectFactory::new()->create();

    Auth::login($user);

    $projects = Project::all();

    expect($projects)->toHaveCount(1);
});

However during the test, both projects are returned. That is because the Auth facade inside the booted function does not return the user which was logged in during the test with: Auth::login($user).

I already tested several other approaches where I manually started the session before logging in the user or using the actingAs helper. However none of those approaches did work. The Auth facade was not returning any user.

Does anyone know how one might be able to use the Auth facade inside of tests?

Kind regards Lars

0 likes
2 replies
LaryAI's avatar
Level 58

The issue you're facing is that the Auth facade is not returning the user that was logged in during the test. This is because the Auth facade in tests does not have access to the session data.

To solve this problem, you can manually set the authenticated user in your test using the actingAs method provided by Laravel's testing framework. Here's how you can modify your test to make it work:

it('only shows projects for the authenticated user', function () {
    $user = UserFactory::new()->create();
    ProjectFactory::new()->user($user)->create();
    ProjectFactory::new()->create();

    $this->actingAs($user);

    $projects = Project::all();

    expect($projects)->toHaveCount(1);
});

By using the actingAs method, you are manually setting the authenticated user for the duration of the test. This will ensure that the Auth facade returns the correct user within your model's global scope.

Make sure to import the TestCase class at the top of your test file:

use Tests\TestCase;

I hope this helps! Let me know if you have any further questions.

larslehmann's avatar

@LaryAI As I wrote in my post, I already tried using the actingAs helper.

I also tried using it by chaining a get method which was directed at an endpoint which would then run a function that returns all projects. That however did not work as well:

it('only shows projects for the authenticated user', function () {
    $user = UserFactory::new()->create();
    ProjectFactory::new()->user($user)->create();
    ProjectFactory::new()->create();

    $projects = $this->actingAs($user)->get('projects')->getContent();

    $projects = json_decode($projects, true);

    expect($projects)->toHaveCount(1);
});
```

Please or to participate in this conversation.