Support the ongoing development of Laravel.io →
Authentication Testing Laravel

I am testing my application (5.8) with the integrated PHPUnit configuration and I have problems with the authentication of a user inside a test.

I have this test (shortened)

public function testShowEditForm($user, $expectedStatus, $expectedLocation, $expectedSee, $expectedDontSee) {
    if ($user !== null)
        $this->actingAs($user);

    // $this->assertAuthenticatedAs($user); -> This is true!

    $response = $this->get("/objects/edit/");

    $response->assertStatus($expectedStatus);

    // [...]
}

with this data provider:

public function showEditFormProvider() {
    return [
        'allowedUser' => [
            UserGenerator::getControllingUser(),
            200,
            null,
            ["something"],
            []
        ]
    ];
}

The UserGenerator::getControllingUser() just triggers the User Factory, adds some rights and returns the user object.

The tested method (also shortened):

public function edit($object_id = null) {
    $user = User::find(Auth::user()->id); // Auth::user() returns null
    // [...]
}

The route for this method is encapsuled inside the "middleware" => "auth" group in the routes/web.php.

Problem: The data provider is correctly called, it passes the middleware but the Auth::user() call in the edit() method returns null - so the authentication seems to have failed anyway regardless the passing through the middleware?

  • If I replace the parameter $user in the testShowEditForm directly with UserGenerator::getControllingUser(), it works (but this isn't a good workaround because I have a lot of test cases and so I need the data providers).
  • So I worked around by calling the data provider by $this->showEditFormProvider() in the first line of the test method testShowEditForm() - but it gets called twice (what is the correct behaviour according to this *). But this is also not the ideal workaround, because if I create an object in the provider to test, it gets created also twice and so the assertions fail. Is there anything I'm doing wrong? I already searched a lot for this topic and the actingAs()/be() methods in the testing method seem to be the best practice for mocking a logged in user.

I already set up a complete fresh installation of Laravel 6 with only the auth routes and nothing else - same problem. Also testing with a MySQL database instead of SQLite made no difference.

Last updated 3 years ago.
0

Try this:

$user = User::find(Auth::id());

Hope this helps,

Ben

Last updated 5 years ago.
0

Thank you! I have no idea why, but this works. Does anyone know about the "internal" difference between my version $user = User::find(Auth::user()->id); and Bens suggestion $user = User::find(Auth::id()); ?

0

Sign in to participate in this thread!

PHPverse

Your banner here too?

M Echelon mechelon Joined 25 Oct 2019

Moderators

We'd like to thank these amazing companies for supporting us

Your logo here?

Laravel.io

The Laravel portal for problem solving, knowledge sharing and community building.

© 2025 Laravel.io - All rights reserved.