Few use cases for PHPUnit's data providers

Janez Cergolj • November 10, 2020

What are they?
Martin Hujer explanation
Tighten's validation example

Validation rules testing

/**
 * @test
 * @dataProvider formValidationProvider
 */
public function test_validation_rules($input, $value)
{
    $response = $this->from(route('create'))
        ->post(route('store'), [$input => $value]);

    $response->assertStatus(Response::HTTP_FOUND)
        ->assertRedirect(route('create'))
        ->assertSessionHasErrors($input);
}

public function formValidationProvider()
{
    return [
        'Test email is required' => ['email', ''],
        'Test email is valid' => ['email', 'email'],
    ];
}

A neat feature that data providers offer is adding text as an array's key if a test fails. In our example: Test email is required.

Here is one of my examples.

A route has applied middleware

/**
 * @test
 * @dataProvider homeRoutesProvider
 * @dataProvider usersRoutesProvider
 */
public function authenticate_middleware_is_applied_for_routes($route)
{
    $this->assertContains('auth', $this->getMiddlewareFor($route));
}

public function homeRoutesProvider()
{
    return [
        'Route home.index doesn\'t have authenticate middleware.' => ['home.index'],
    ];
}

public function usersRoutesProvider()
{
    return [
        'Route users.index doesn\'t have authenticate middleware.' => ['users.index'],
        'Route users.create doesn\'t have authenticate middleware.' => ['users.create'],
        'Route users.edit doesn\'t have authenticate middleware.' => ['users.edit'],
    ];
}

You can apply as many as you wish data providers to a single test.

/**
 * @test
 * @dataProvider homeRoutesProvider
 * @dataProvider usersRoutesProvider
*/

Here is one of my examples.

As you can see data providers might reduce number of tests needed in your test suite. Use them where you think it makes sense.