Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I access the number of the dataProvider's current data set?

Tags:

php

phpunit

In PHPUnit, for a test decorated with a @dataProvider, is there a way to find out the index of the dataset (within the array provided by the dataProvider) being currently used?

like image 422
Bernhard Reiter Avatar asked Dec 04 '14 17:12

Bernhard Reiter


1 Answers

Method 1 - Format Array

You have to format your dataProvider method to supply the array index ($key) as well as the $value:

<?php

class DataProviderTest extends \PHPUnit_Framework_TestCase
{
    /**
     * @dataProvider provider
     */
    public function testMethod($key, $value)
    {
        if ($key === 1) {
            $this->assertEquals('two', $value, 'pass');
        }

        if ($key === 2) {
            $this->assertEquals('two', $value, 'fail');
        }
    }

    public function provider()
    {
        $data = array('one', 'two', 'three');

        $holder = array();
        foreach ($data as $key => $value) {
            $holder[] = array($key, $value);
        }

        return $holder;
    }
}

As you can see above, I formatted the provider to supply the key and value in two method arguments..

Method 2 - Call private property

Since your comment I have done some more digging and I have found the method that PHPUnit are using internally to get the dataProvider array index on failure, the index is stored in a private property of the test case class (PHPUnit_Framework_TestCase) called dataName.

I am mainly a Magento developer and we use the EcomDev_PHPUnit module to help with testing, it comes with a nice reflection helper to access restricted properties since Magento is not built for testing and has a lot of them, see: https://github.com/EcomDev/EcomDev_PHPUnit/blob/master/lib/EcomDev/Utils/Reflection.php

I can not find a public accessors for this property so you will have to use reflection, maybe you can open a pull request?

<?php

class DataProviderTest extends \PHPUnit_Framework_TestCase
{

    /**
     * @dataProvider provider
     */
    public function test($value)
    {
        $key = EcomDev_Utils_Reflection::getRestrictedPropertyValue($this, 'dataName');

        if ($value === 'zero') {
            $this->assertEquals($key, '0', 'pass');
        }

        if ($value === 'two') {
            $this->assertEquals($key, '1', 'fail');
        }
    }

    public function provider()
    {
        return array(
            array('zero'),
            array('one'),
            array('two')
        );
    }
}
like image 163
jzahedieh Avatar answered Nov 07 '22 13:11

jzahedieh