Phpunit: Data Provider Argument Count Error

Created on 19 Dec 2016  ·  4Comments  ·  Source: sebastianbergmann/phpunit

I am using the latest version of PHPUnit (5.7.4). The problem is when I run test, it passes. But if I run it once again, it fails with the following error:

ArgumentCountError: Too few arguments to function ValidationTest::testValidateType(), 0 passed and at least 3 expected

If I make any changes to the data provider function (i.e. change the data to be returned, provider function name or type etc.) and re-run, it passes for once and fails with the above error for all consecutive test runs.

Not sure, but does PHPUnit use any caching mechanism to cache provider data? If yes, then is there any way to clean it (maybe using setUp or tearDown)?


The following code work once (pass once):

/**
 * @covers Validation
 * @coversDefaultClass Validation
 */
class ValidationTest extends TestCase {

    protected $validation;


    protected function setUp() {
        $this->validation = new Validation();
    }


    /**
     * @covers ::validateType
     * @dataProvider validateTypeProdiver
     */
    public function testValidateType($assertion, $argument, $type) {
        $result = $this->validation->validateType($argument, $type);

        switch ($assertion) {
            case 'True':
                $this->assertTrue($result);
                break;
        }
    }


    public function validateTypeProdiver() {
        return [
            ['True', 'file.txt', 'str']
       ];
    }
}

The following code always work (passes everytime):

/**
 * @covers Validation
 * @coversDefaultClass Validation
 */
class ValidationTest extends TestCase {

    protected $validation;


    protected function setUp() {
        $this->validation = new Validation();
    }


    /**
     * @covers ::validateType
     */
    public function testValidateType() {
        foreach ($this->validateTypeProdiver() as $args) {
            $result = call_user_func_array([$this->validation, 'validateType'], array_slice($args, 1));

            switch ($args[0]) {
                case 'True':
                    $this->assertTrue($result);
                    break;
            }
        }
    }


    public function validateTypeProdiver() {
        return [
            ['True', 'file.txt', 'str']
       ];
    }
}

Most helpful comment

If somebody somewhen encountered this problem.
I had this test

class Test extends TestCase {
    protected $tested;

    public function __construct()
    {
        parent::__construct();
        $this->tested = new TestedClass();
    }

    public function provider(): array
    {
        return array(
            array(0, 1, 1),
            array(1, 2, 3),
        );
    }

    /**
     * @dataProvider provider
     */
    public function testSum(int $first, int $second, int $expected)
    {
        $this->assertEquals($expected, $this->tested->sum($first + $second));
    }
}

I changed __construct to setUp and it works.

All 4 comments

I'm not able to reproduce the issue with your provided information. Here's what I did:

$ composer require phpunit/phpunit:5.7.4
$ vendor/bin/phpunit && vendor/bin/phpunit

$ vendor/bin/phpunit && vendor/bin/phpunit 
PHPUnit 5.7.4 by Sebastian Bergmann and contributors.

Runtime:       PHP 7.0.17-2+deb.sury.org~trusty+1
Configuration: /.../phpunit.xml

.                                                                   1 / 1 (100%)

Time: 44 ms, Memory: 4.00MB

OK (1 test, 1 assertion)
PHPUnit 5.7.4 by Sebastian Bergmann and contributors.

Runtime:       PHP 7.0.17-2+deb.sury.org~trusty+1
Configuration: /.../phpunit.xml

.                                                                   1 / 1 (100%)

Time: 32 ms, Memory: 4.00MB

OK (1 test, 1 assertion)

This is the test class I used:

use PHPUnit\Framework\TestCase;

class TestMeTest extends TestCase
{

    protected $validation;

    protected function setUp()
    {

        $this->validation = new Validation();
    }

    /**
     * @covers ::validateType
     * @dataProvider validateTypeProdiver
     */
    public function testValidateType($assertion, $argument, $type)
    {

        $result = $this->validation->validateType($argument, $type);

        switch ($assertion) {
            case 'True':
                $this->assertTrue($result);
                break;
        }
    }

    public function validateTypeProdiver()
    {

        return [
            ['True', 'file.txt', 'str']
        ];
    }
}

And the Validation class:

class Validation
{
    public function validateType() {
        return true;
    }
}

PHPUnit does not cache data providers persistently.

I also cannot reproduce this.

If somebody somewhen encountered this problem.
I had this test

class Test extends TestCase {
    protected $tested;

    public function __construct()
    {
        parent::__construct();
        $this->tested = new TestedClass();
    }

    public function provider(): array
    {
        return array(
            array(0, 1, 1),
            array(1, 2, 3),
        );
    }

    /**
     * @dataProvider provider
     */
    public function testSum(int $first, int $second, int $expected)
    {
        $this->assertEquals($expected, $this->tested->sum($first + $second));
    }
}

I changed __construct to setUp and it works.

@dmirogin's solution made my day, phpunit 8.5

Was this page helpful?
0 / 5 - 0 ratings

Related issues

sebastianbergmann picture sebastianbergmann  ·  4Comments

gellis picture gellis  ·  4Comments

ezzatron picture ezzatron  ·  3Comments

sebastianbergmann picture sebastianbergmann  ·  3Comments

greg0ire picture greg0ire  ·  4Comments