Summer Sale! All accounts are 50% off this week.

jeFFF's avatar
Level 3

Is there a way to optimise assertDatabaseHas ?

Hello there, I want to test that a great set of permissions are created with a function. With pest, I did this :

it('should have these permissions defined for backend', function () {
    $this->assertDatabaseHas(
        'permissions',
        [
            'name' => $role,
           	'guard_name' => 'backpack'
        ]
    );
})
->with('my_great_array_here');

My test is passing fine ! The issue is that I have 140 permissions and it will grow and the test took ages ! Is there a way to optimise this ?

Thanks for your help.

0 likes
4 replies
LaryAI's avatar
Level 58

One way to optimize assertDatabaseHas is to use the where method to filter the results before checking if the record exists. This can be done by passing an array of conditions to the where method. For example:

it('should have these permissions defined for backend', function () {
    $permissions = [
        'name' => $role,
        'guard_name' => 'backpack'
    ];
    $this->assertDatabaseHas('permissions', function ($query) use ($permissions) {
        foreach ($permissions as $column => $value) {
            $query->where($column, $value);
        }
    });
})
->with('my_great_array_here');

This will only check if a record exists in the "permissions" table where the "name" and "guard_name" columns match the values in the $permissions array. This can significantly reduce the number of records that need to be checked, and therefore improve the performance of the test.

tisuchi's avatar

@jefff It seems you already used datasets. I don't think it can be optimized more!

tykus's avatar

This is an odd test. Are you testing against data in your live database?

The only way I can think to optimise this test is to build a count query to check that the number of results returned matches the number of elements in the result. This would be based on building a query like:

SELECT COUNT(*)
FROM `permissions`
WHERE (
  (`name` = "admin" AND `guard_name` = "backpack") OR
  (`name` = "other" AND `guard_name` = "backpack") OR
  -- ...
);

It is trivial to build the query in PHP; however, it will not tell you which permission might be missing.

1 like
jeFFF's avatar
Level 3

@tykus no, it's not on my live database.

The project is quite complex and I might add / remove / update permissions at any time, I want to ensure that I'm not missing to create.

I about your solution, I didn't thought of it, I will give it a try. Thanks !

Please or to participate in this conversation.