Home > Backend Development > PHP Tutorial > Using Eloquent Factories With PHPUnit Data Providers

Using Eloquent Factories With PHPUnit Data Providers

Emily Anne Brown
Release: 2025-03-06 02:40:08
Original
465 people have browsed it

Using Eloquent Factories With PHPUnit Data Providers

There are several ways to use the Eloquent factory in Laravel feature testing, for example, when you want to use the model for multiple tests, you can create a model during

or directly in a single test case. If you have a test case that needs to be tested against various data, you may need to use the Eloquent model and PHPUnit's data provider. setUp()

Using data providers in feature testing may have problems as they run before the framework's

boots Laravel via TestCase. The data providers are parsed very early during the run setUp(), so if you want to use them, you will encounter the following error: phpunit

<?php namespace Tests\Feature;

use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use PHPUnit\Framework\Attributes\DataProvider;
use Tests\TestCase;

class ExampleTest extends TestCase
{
    use RefreshDatabase;

    #[DataProvider('nonAdminUsers')]
    public function test_non_admin_users_cannot_access_admin($user): void
    {
        $response = $this
            ->actingAs($user())
            ->get('/admin')
            ->assertStatus(403);
    }

    public static function nonAdminUsers(): array
    {
        return [
            [User::factory()->player()->create()],
            [User::factory()->coach()->create()],
            [User::factory()->owner()->create()],
        ];
    }
}
Copy after login
When running the above test you should get errors like the following, depending on the version of Laravel you are using - Here is the error I got on Laravel 11:

<code>$ vendor/bin/phpunit tests/Feature/ExampleTest.php

There was 1 PHPUnit error:

1) Tests\Feature\ExampleTest::test_non_admin_users_cannot_access_admin
The data provider specified for Tests\Feature\ExampleTest::test_non_admin_users_cannot_access_admin is invalid
A facade root has not been set.

tests/Feature/ExampleTest.php:18</code>
Copy after login
This is because when the data provider code is running, the Laravel application has not started yet! If you are a Pest PHP user, the Bound Datasets example shows how to use closures for model data:

it('can generate the full name of a user', function (User $user) {
    expect($user->full_name)->toBe("{$user->first_name} {$user->last_name}");
})->with([
    fn() => User::factory()->create(['first_name' => 'Nuno', 'last_name' => 'Maduro']),
    fn() => User::factory()->create(['first_name' => 'Luke', 'last_name' => 'Downing']),
    fn() => User::factory()->create(['first_name' => 'Freek', 'last_name' => 'Van Der Herten']),
]);
Copy after login
In PHPUnit, we can pass code to our tests through a data provider using closures without having to try to create data immediately:

namespace Tests\Feature;

use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use PHPUnit\Framework\Attributes\DataProvider;
use Tests\TestCase;

class ExampleTest extends TestCase
{
    use RefreshDatabase;

    #[DataProvider('nonAdminUsers')]
    public function test_non_admin_users_cannot_access_admin($user): void
    {
        $response = $this
            ->actingAs($user())
            ->get('/admin')
            ->assertStatus(403);
    }

    public static function nonAdminUsers(): array
    {
        return [
            [fn(): User => User::factory()->player()->create()],
            [fn(): User => User::factory()->coach()->create()],
            [fn(): User => User::factory()->owner()->create()],
        ];
    }
}
Copy after login
Please note the

call, we pass it to $user(). If you need to use the model in a different place, just assign it to a variable. Now, the factory data is created in testing, which is exactly what we want! To learn more about HTTP feature testing in Laravel, check out the documentation. actingAs()

The above is the detailed content of Using Eloquent Factories With PHPUnit Data Providers. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Articles by Author
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template