Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHPUnit @dataProvider simply doesn't work

Tags:

php

phpunit

I've read the documentation on the topic, and my code follows all requirements of a data provider implementation. First of all, here's the full code of the test just in case it's relevant.

Here's the function implementing data provider:

/**
 * Test the createGroup function
 *
 * @return void
 * @author Tomas Sandven <[email protected]>
 *
 * @dataProvider provideFileImportTests_good
 **/
public function testCreateGroup($file, $groupname, $group, $mapping)
{
    // Create a test group
    $id = $this->odm->createGroup($groupname, $group);

    // Try to load it back out
    $result = R::load(OmniDataManager::TABLE_GROUP, $id);

    // Check that the result is not null
    $this->assertFalse(is_null($result));

    return $id;
}

PHPUnit just fails:

Missing argument 1 for tests\broadnet\broadmap\OmniDataManagerTest::testCreateGroup()

I've tried killing the application (die();) inside the data provider function, and it never happens. The data provider function is available publicly in the same class, there are no typos in the function name and the testCreateGroup function references it in the annotations in the comment, but the data provider function is never called.

Does anybody know why?

like image 663
Hubro Avatar asked Apr 16 '12 13:04

Hubro


4 Answers

Finally after hours of prodding this test file, I discovered that merely defining the constructor function breaks the functionality of data providers. Good to know.

To fix it, just call the parent constructor. Here's how that looked in my case:

public function __construct()
{
    // Truncate the OmniDataManager tables
    R::wipe(OmniDataManager::TABLE_GROUP);
    R::wipe(OmniDataManager::TABLE_DATA);

    parent::__construct();   // <- Necessary
}

As David Harkness and Vasily pointed out in the comments, the constructor override must match the call signature of the base class constructor. In my case the base class constructor didn't require any arguments. I'm not sure if this has just changed in newer versions of phpunit or if it depends on your use case.

In any case, Vasily's example might work better for you:

public function __construct($name = null, array $data = array(), $dataName = '')
{
    // Your setup code here

    parent::__construct($name, $data, $dataName)
}
like image 193
Hubro Avatar answered Nov 18 '22 18:11

Hubro


If you really need it, David Harkness had the right tip. Here's the code:

public function __construct($name = NULL, array $data = array(), $dataName = '') {
    $this->preSetUp();
    parent::__construct($name, $data, $dataName);
}
like image 30
Jon Gilbert Avatar answered Nov 18 '22 20:11

Jon Gilbert


To emphasise the point that micro_user made, the @dataProvider annotation must be in a docblock comment. i.e. do this:

/**
 * @dataProvider myDataProvider
 *
 */
public function testMyMethod(...)
{
  ...
}

Don't do this since it won't work:

/*
 * @dataProvider myDataProvider
 *
 */
public function testMyMethod(...)
{
  ...
}
like image 20
darrenp Avatar answered Nov 18 '22 20:11

darrenp


For me only removing the constructor has worked. Calling the parent constructor inside my class test broke the annotations as well even with the latest stable version of PHPUnit (6.0.9).

I just moved the code I had on __constructor to the setUp function that is called before my unit tests run.

like image 15
Amaynut Avatar answered Nov 18 '22 19:11

Amaynut