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

rezamk's avatar

Roles and Permissions with PHPUnit

Hi,

I am trying to work out how I can extend the tutorial at https://laracasts.com/series/whats-new-in-laravel-5-1/episodes/16 to add some basic tests around the applied permissions.

The issue is that the boot method is called before the unit test starts to run, which contains:

    // Dynamically register permissions with Laravel's Gate.
    foreach ($this->getPermissions() as $permission) {
        $gate->define($permission->name, function ($user) use ($permission) {
            return $user->hasPermission($permission);
        });
    }

Full class code here: https://github.com/laracasts/laravel-5-roles-and-permissions-demo/blob/master/app/Providers/AuthServiceProvider.php

The test below therefore always fails, since the database has not been populated until after the boot method is called.

use DatabaseTransactions;

/**
 * A basic test example.
 *
 * @return void
 */
public function testBasicTest()
{
    $this->seed('UserModelSeeder');
    ... other stuff
    $this->assertTrue(Gate::forUser($someUser)->allows('create'));
}

How can I get the ordering correct here, without changing the database data for each test? If I don't use DatabaseTransactions, the second time I run the test, I expect it will work. But ofcourse, it will duplicate the data every time!

I guess mocking is an option, but I would like to work out if it is possible to do this without since these will act as regression tests rather than unit.

Many thanks!

0 likes
2 replies
jrdavidson's avatar

I am currently trying to solve this issue as well. Has anyone tried to test permissions for this before?

jrmorales's avatar

try disabling ExceptionHandling in your test


use DatabaseTransactions;

/**
 * A basic test example.
 *
 * @return void
 */
public function testBasicTest()
{
    $this->withoutExceptionHandling();
    $this->seed('UserModelSeeder');
    //... other stuff
    $this->assertTrue(Gate::forUser($someUser)->allows('create'));
}

Please or to participate in this conversation.