How to pass an array as an argument from providers in PHPUnit?

Viewed 9533

I have a test method that receives an array as an argument, and I want to feed the data from a data provider method?

how can that be achieved?

public function dataProvider(){
        return array(array(
                'id'=>1,
                'description'=>'',
        ));
}

/**
 * @dataProvider dataProvider
 */
public function testAddDocument($data){
// data here shall be an array provided by the data provider
// some test data here
}

What happens is that it passes the value of 'id' key ...etc

I want to pass the whole array

2 Answers

For clarity, I like to write the providers building variables that name what is what. Clean Coding rulez.

For this example, I'll start with a simple data provider that gets 2 phone numbers and 2 numbers. At the end I go with your particular example.

First of all, I always name the $tests variable, which makes it clear I'm going to return an "array of items representing a test":

public function successProvider() : array
{
    $tests = [
        [ '+11 111 11 11 111', '+11 111 11 11 111', 1, 2 ],
        [ '+11 111 11 11 111', '+55 555 55 55 555', 2, 3 ],
    ];

    return $tests;
}

If the test cases get more complex, I name them one by one assigning a key in the array:

public function successProvider() : array
{
    $tests = [
        'same phone' => [ '+11 111 11 11 111', '+11 111 11 11 111', 1, 2 ],
        'phone changed' => [ '+11 111 11 11 111', '+55 555 55 55 555', 2, 3 ],
    ];

    return $tests;
}

If each test case gets more complex I name each one in separated variables, like this:

public function successProvider() : array
{
    $testSamePhone = [
        '+11 111 11 11 111',
        '+11 111 11 11 111',
        1,
        2,
    ];

    $testPhoneChanged = [
        '+11 111 11 11 111',
        '+55 555 55 55 555',
        2,
        3,
    ];

    $tests = [
        $testSamePhone,
        $testPhoneChanged,
    ];

    return $tests;
}

To clarify what is each thing, some times I set a key inside each test. I usually make those keys similar to the variable names in the test receiving the parameters. Looks like this:

public function successProvider() : array
{
    $testSamePhone = [
        'possibleNumber' => '+11 111 11 11 111',
        'realNumber' => '+11 111 11 11 111',
        'numberOfLogCalls' => 1,
        'numberOfEvents' => 2,
    ];

    $testPhoneChanged = [
        'possibleNumber' => '+11 111 11 11 111',
        'realNumber' => '+55 555 55 55 555',
        'numberOfLogCalls' => 2,
        'numberOfEvents' => 3,
    ];

    $tests = [
        $testSamePhone,
        $testPhoneChanged,
    ];

    return $tests;
}

Now it becames super readable and without the need of "comments" (Clean Code rules advocates for the code speaking by itself).

Now, what if the input phone number instead of a number is an array of numbers? Say instead of "one possibleNumber" we have "a set of possibleNumbers":

public function successProvider() : array
{
    $testSamePhone = [
        'possibleNumbers' => [ '+11 111 11 11 111', '+3 333 333', '+999 999 9 9 9 9' ],
        'realNumber' => '+11 111 11 11 111',
        'numberOfLogCalls' => 1,
        'numberOfEvents' => 2,
    ];

    $testPhoneChanged = [
        'possibleNumbers' => [ '+11 111 11 11 111', '+3 333 333',  ],
        'realNumber' => '+55 555 55 55 555',
        'numberOfLogCalls' => 2,
        'numberOfEvents' => 3,
    ];

    $tests = [
        $testSamePhone,
        $testPhoneChanged,
    ];

    return $tests;
}

In your case

I'd write the data provider like this:

public function dataProvider() : array
{
    $testDescriptiveNameOfTheTestCase = [
        'data' => [ 'id' => 1, 'description' => '' ],
    ];
    
    $tests = [
        $testDescriptiveNameOfTheTestCase,
    ];
    
    return $tests;
}

or, more compact:

public function dataProvider() : array
{
    $tests = [
        'Descriptive name of the Test Case' => [
            'data' => [ 'id' => 1, 'description' => '' ],
        ],
    ];

    return $tests;
}
Related