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

outofcontrol's avatar

Unable to get phpunit to test user role correctly

The goal is to test if the administrator to a site can see the administration dashboard. We are using Laravel 8 with Spatie laravel-permission v3.18. Roles work correctly when testing manually in the browser.

My code

// routes/web.php
Route::group(['middleware' => ['role:admin']], function () {
    Route::middleware(['auth:sanctum', 'verified'])->get('/administration', function () {
        return view('admin.index');
    })->name('administration');
});
//tests/Feature/AdministrationTest.php

<?php

namespace Tests\Feature;

use Tests\TestCase;
use App\Models\User;
use Spatie\Permission\Models\Role;
use Spatie\Permission\PermissionRegistrar;
use Illuminate\Foundation\Testing\RefreshDatabase;

class AdministrationTest extends TestCase
{

    use RefreshDatabase;

    protected $admin;

    public function setUp(): void
    {
        parent::setUp();
        $this->setupPermissions();

        $this->admin = User::factory()->make();
        $this->admin->assignRole('admin');
        $this->admin->save();
    }

    protected function setUpPermissions()
    {
        Role::create(['name' => 'admin']);

        $this->app->make(PermissionRegistrar::class)->registerPermissions();
    }
    
    /** @test  */
    public function an_admin_can_browse_admin_dashboard()
    {
        $this->withoutExceptionHandling();
        $admin = User::find(1);

        $response = $this
            ->actingAs($admin)
            ->get('/administration');

        $response->assertStatus(200);
    }
// result of phpunit

There was 1 error:

1) Tests\Feature\AdministrationTest::an_admin_can_browse_admin_dashboard
Spatie\Permission\Exceptions\UnauthorizedException: User does not have the right roles.
  • Using dd($this->admin->getRoleNames()) after the user has been created and role assigned, shows that the user has no roles, which explains the user
  • Testing has been done both with saving the user as above and not saving the user. Same result.
  • Examples above used from this Spatie Permissions Demo here and here

What changes to my code are necessary to allow this test to work successfully?

0 likes
3 replies
jlrdw's avatar

But how about authorization. I am sure laravel is tested to ensure the logged in user can do something.

I would be more concerned if authorization is ensuring the logged in user can or cannot do the things assigned.

I don't look at how important a role is, like many people make a big deal about admin, I have a system where you have admins and bookkeepers but the admin cannot mess around with bookkeeping or accounting.

That would be of a higher concern to me, the can or cannot do something.

I would guarantee you that authentication out of the box is tested and probably retested by Taylor and the laravel team.

outofcontrol's avatar

Authorization appears to test just fine. This is a simple test to see if a role of admin can access a specific page. Am I missing your point?

outofcontrol's avatar

Thinking more about what @jlrdw commented on, I altered my Route::group to be:

Route::group(['middleware' => ['auth:sanctum', 'verified', 'role:admin']], function () {

The problem is now resolved. Though I am tot sure why. If I had to guess, Perhaps having auth:sanctum called before role:admin would be setup the user and roles to be available?

Please or to participate in this conversation.