Phpunit: Can't pass a parameter with @dataProvider + @depends

Created on 26 Feb 2011  路  10Comments  路  Source: sebastianbergmann/phpunit

I'm expecting the below code returns no failure. But on testDataReceiver(), $a will be null unexpectedly. I'm not sure if it's a bug. Can anyone test this code or correct my code? Thanks.

PHPUnit 3.5.11, PHP 5.3.3

<?php

class DataProviderTest extends PHPUnit_Framework_TestCase
{
    const TEST_NUM = 7;
    /**
     *  @dataProvider provider
     */
    public function testDataProvider($a)
    {
        $this->assertTrue($a === self::TEST_NUM);
        return $a;
    }
    /**
     *  @depends testDataProvider
     */
    public function testDataReceiver($a)
    {
        // somehow $a will be null
        $this->assertTrue($a === self::TEST_NUM);
    }
    public function provider()
    {
        return array(array(self::TEST_NUM));
    }
}

Most helpful comment

I understand the explanation given by @elblinkin which explains why @nobuf expected behaviour is different from the real phpunit behaviour.
But from my point of view, @depends should understand that testDataProvider will be "cloned" and run multiple times so testDataReceiver should be run also multiple times: each time testDataProvider is run with a given dataset, then testDataReceiver should be run with the testDataProvider returned data as input.

All 10 comments

The @dataProvider annotations get computed before test execution. Basically, the pre-test phase creates a test method for every set of parameters provided by the data provider. The @depends is dependent upon what is essentially the prototype of the data driven test, so in a way the @depends is on a non-existent (not executed test).

Another way to think of it, is that if provider was supplying more than one set of parameters. PHPUnit would make that many testDataProvider methods but there would not be that many testDataReceiver methods because there is not an @dataProvider method on that test method for the pre-test phase.

You can however had @depends and @dataProvider on the same test method. Just be careful to get the parameter order right, although in this case there may not be a first parameter.

Thanks for the explanation. That makes sense. Appreciate it.

Hey there is actually a pattern in order to build test dependencies into data providers using @depends & @dataProvider. http://beagile.biz/nested-data-provider-with-dependency-in-phpunit/

I understand the explanation given by @elblinkin which explains why @nobuf expected behaviour is different from the real phpunit behaviour.
But from my point of view, @depends should understand that testDataProvider will be "cloned" and run multiple times so testDataReceiver should be run also multiple times: each time testDataProvider is run with a given dataset, then testDataReceiver should be run with the testDataProvider returned data as input.

why is this closed?
I have the opinion, too, that @depends should be aware of @dataprovider of the dependet test method.

Anything changed in that matter? Is there any way to run @depends with @dataProvider without looping inside test?

Can we re-open this issue?
Seem like a legitimate use case

This issue shall not be closed.
Stills being an issue on @depends which provides no return data to dependent tests.
I'm facing how could I get the return of a test as the input for the dependent, but If I use a @dataProvider on the first test, its dependent just receives NULL as input.

This issue shall not be closed.
Stills being an issue on @depends which provides no return data to dependent tests.
I'm facing how could I get the return of a test as the input for the dependent, but If I use a @dataProvider on the first test, its dependent just receives NULL as input.

@temple - that is correct and I wonder there is no concrete solution for this yet.

Just started to write tests recently and immediately stepped into this bug. So weird it is still not resolved and there is no good workaround. So now I have to rewrite my tests into something ugly without data providers and with custom error messages.

My case (simplified example):

class MyTest extends TestCase
{
    public function cache100(): array
    {
        return [/* 100 values here */];
    }

    /**
     * @dataProvider cache100
     * @param array $entry
     * @return array
     */
    public function testA(array $entry): array
    {
        //some heavy calculation here...
        return [/* result */];
    }

    /**
     * @dataProvider cache100
     * @param array $entry
     * @return array
     */
    public function testB(array $entry): array
    {
        //some heavy calculation here...
        return [/* result */];
    }

    /**
     * @dataProvider cache100
     * @depends      testA
     * @depends      testB
     */
    public function testC(array $entry, array $valueA, array $valueB)
    {
        $valueC = $valueA * $valueB;
    }
}

Now I think the only way to make it work is refuse from dataProviders in testA and testB and rewrite the code into loops. But this is ugly :(

Was this page helpful?
0 / 5 - 0 ratings