Mocking Authenticated Users in Laravel's Request

December 19th, 2024 • 1 minute read time

I recently found myself writing a test where I needed to test a macro applied to the Request object in Laravel. But I needed the user to be 'authenticated'.

Here's how to mock authenticated users in Laravel's Request object.

First, here's the macro I added to the Request object, which returns the user's currently associated team. This isn't important, but some context may help.

Request::macro('team', function () {
    return $this->user()?->currentTeam;
});

If we were to write a test like this, it wouldn't work:

it('can access the current team through the request', function () {
    $user = User::factory()->create();

    expect(request()->team())->toBeInstanceOf(Team::class);
});

We don't want to (and can't) use actingAs here to authenticate the user. Nor can we use auth()->login($user).

So, the solution is to set the user resolver like this:

it('can access the current team through the request', function () {
    $user = User::factory()->create();

    request()->setUserResolver(function () use ($user) {
        return $user;
    });

    expect(request()->team())->toBeInstanceOf(Team::class);
});

Now, when the macro I created for Request invokes user(), it'll return the user defined in the test.

You can further shorten this down, too, with a short arrow function:

it('can access the current team through the request', function () {
    $user = User::factory()->create();

    request()->setUserResolver(fn () => $user);

    expect(request()->team())->toBeInstanceOf(Team::class);
});

That's it. If you need to assume an authenticated user in tests that don't make an HTTP request, override the user resolver with setUserResolver.

If you found this article helpful, you'll love our practical screencasts.
Author
Alex Garrett-Smith
Share :

Comments

No comments, yet. Be the first!

Tagged under