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

BrokeYourBike's avatar

Sanctum API requests testing

Why we can get access the route protected by auth:sanctum with User that has no access tokens? Is this made for tests simplicity?

class PingTest extends TestCase
{
    use RefreshDatabase;

    /** @test */
    public function guest_cannot_ping()
    {
        $this->json('get', 'api/v1/ping')->assertStatus(401);
    }
	
    /** @test */
    public function customer_can_ping()
    {
        $user = User::factory()->create();
        $this->assertCount(0, $user->tokens);

        $this->actingAs($user);

        $this->json('get', 'api/v1/ping')->assertStatus(200);
    }

}

I am expecting the second test to fail, because user has not tokens, but it passes.

0 likes
4 replies
chaudigv's avatar

According to Sanctum Testing, it says to use

Sanctum::actingAs(User::factory()->create());

$this->json('get', 'api/v1/ping')->assertStatus(200);
3 likes
martinbean's avatar
Level 80

@brokeyourbike Why are you expecting the second test to fail? You’re authenticating as a user (actingAs) and then asserting the status code is 200 (OK).

Unless you specify a guard, Laravel will just spin through all the ones configured for your application. If it manages to authenticate a user with one, then the user is authenticated. So it will check the default (web) guard first, see the user’s authenticated (because you used actingAs to authenticate them) and then allow the request.

If you want the sanctum guard to be explicitly used, then you may specify it as the second parameter of the actingAs method:

$this
    ->actingAs($user, 'sanctum')
    ->getJson('api/v1/ping')
    ->assertOk();
4 likes
BrokeYourBike's avatar

I expected the second test to fail because current authenticated user do not have any tokens. But from what I see when I use actingAs method, passed model will be authenticated no matter what. Thanks for the answer, I think it's clear for me now.

1 like
robmpreston's avatar

I'd expect to be able to pass a third param with sanctum token abilities. It seems I have to call Sanctum::actingAs() instead. No fluent interface then.

Please or to participate in this conversation.