Проблема с PHPUnit и поставщиками данных - PullRequest
19 голосов
/ 24 ноября 2010

У меня есть следующий контрольный пример:

include_once('../Logger.php');

class LoggerTest extends PHPUnit_Framework_TestCase {

    public function providerLogger() {
        return new Logger;
    }

    /**
     * @dataProvider providerLogger
     */
    public function testAddStream($logger) {
        $this->assertTrue(false);
    }

}

Когда я запускаю его в PHPUnit, я получаю:

PHPUnit 3.4.14 by Sebastian Bergmann.

..........

Time: 0 seconds, Memory: 5.75Mb

OK (1 tests, 0 assertions)

Проверка должна завершиться неудачей, но это не так.Я попытался получить:

public function providerLogger() {
    return array(new Logger);
}

Но я получил:

The data provider specified for LoggerTest::testAddStream is invalid.

Я попытался объявить его static (как сказано в руководстве), но все равно без разницы.

Я помню, что раньше он работал аналогичным образом, но я могу ошибаться.Чего мне не хватает?

Заранее спасибо за помощь.

PHPUnit 3.4.14 (взят из PEAR) на PHP 5.3.3

Ответы [ 6 ]

30 голосов
/ 24 ноября 2010

Незначительное обновление: нормально использовать методы экземпляра в качестве провайдера, начиная с версии 3.2 (или где-то около этого).Посмотрите на комментарии


Поставщик должен выглядеть следующим образом.

public static function providerLogger() {
    return array(
      array(new Logger)
    );
}

Прежде всего: метод должен быть static , если вы используетеВерсия phpunit ниже 3.3.

Массив s важен.Это не так сложно понять.Внешний массив имеет одно значение для каждой итерации, которую должен вызывать тест.Здесь тест просто вызывают один раз.Внутренние массивы - это параметры (по порядку), с которыми вызывается тест.Ваш тест ожидает ровно один параметр, поэтому внутренним массивам всегда нужно ровно одно значение.Еще один небольшой пример

public static function addTestProvider () {
    return array(
        /* First + Second = third? */
        array(1,4,5),
        array(3,3,6),
        array(5,5,6)
    );
}
public function testAdd ($a, $b, $result) {
    $this->assertEquals($result, $a + $b);
}

Здесь testAdd выполняется 3 раза, по одному для каждого второго уровня массив , и он получает значения из внутреннего массив с.Вы можете заметить, что тест не пройден и выдает сообщение, в котором итерация набора данных (здесь # 3, потому что 5 + 5 не 6;)) завершилась неудачей.

5 голосов
/ 25 августа 2011

У меня была такая же проблема, и она была решена, когда я удалил пустой конструктор, который был сгенерирован автоматически. Я не уверен, почему это решает проблему. У меня также не было никакого метода испытания, названного как класс. Метод провайдера не должен быть статическим, пока мой тестовый прогон без статического. Но также запускается, когда я делаю метод провайдера статическим

1 голос
/ 15 сентября 2011
<?php

require_once 'calculator.php';

/**
 * Calculator test case.
 */
class CalculatorTest extends PHPUnit_Framework_TestCase {

    /**
     * @var Calculator
     */
    private $Calculator;

    /**
     * Prepares the environment before running a test.
     */
    protected function setUp() {
        parent::setUp ();
        // TODO Auto-generated CalculatorTest::setUp()
        $this->Calculator = new Calculator(/* parameters */);
    }

    /**
     * Cleans up the environment after running a test.
     */
    protected function tearDown() {
        // TODO Auto-generated CalculatorTest::tearDown()
        $this->Calculator = null;
        parent::tearDown ();
    }

    /**
     * Constructs the test case.
     */
    public function __construct() {
        // TODO Auto-generated constructor
    }

    /**
     * Tests Calculator->add()
     *
         * @dataProvider provider
         */
    public function testAdd($a, $b, $c) {
        // TODO Auto-generated CalculatorTest->testAdd()
        //$this->markTestIncomplete ( "add test not implemented" );

        //$this->Calculator->add(/* parameters */);
        $this->assertEquals($this->Calculator->add($a, $b), $c);
    }

    public static function provider()
    {
        return array(
          array(1, 1, 1),
          array(1, 1, -1),
          array(4, 2, 2),
          array(1, 1, 1)
        );
    }
}

- это полный набор кода

0 голосов
/ 16 февраля 2013

Вот, я получил шаблон для достижения тестовых зависимостей для провайдеров данных!Таким образом вы можете связать dataProviders.

class ProviderDependencyTest extends PHPUnit_Framework_TestCase
{
    private static $dataSet;

    public function provideData()
    {
        self::$dataSet = array(
                    array(2,2,4),
                    array(1,0,2),
                    array(0,0,0)
                );

        //use static storage so you don't have to call the dataProvider again
        return self::$dataSet;
    }

    public function testProvideAdd()
    {
        $data = self::$dataSet;

        $this->assertEquals(3,count($data[0]));

        return $data[0];
    }

    /**
     * @depends testProvideAdd
     */
    public function testAdd($data)
    {
        $sum = $data[0] + $data[1];

        $this->assertEquals($data[2], $sum);

        return array($sum,$data[0],$data[1]);
    }

    /**
     * @depends testAdd
     */
    public function testSubtract($data)
    {
        $difference = $data[0] - $data[1];

        $this->assertEquals($data[2], $difference);

        return array($difference,$data[0],$data[1]);
    }

    /**
     * @depends testSubtract
     */
    public function testMultiply($data)
    {
        $product = $data[0] * $data[2];

        $this->assertEquals($data[1], $product);

        return $product;
    }

    /**
     * @depends testMultiply
     *
     * @dataProvider provideData
     */
    public function testMath($a,$b,$c)
    {
        //don't redo the first set of tests
        if(array($a,$b,$c) == self::$dataSet[0])
        {
            return;
        }

        $sum = $this->testAdd(array($a,$b,$c));
        $difference= $this->testSubtract($sum);
        $product = $this->testMultiply($difference);

        $this->assertInternalType('integer', $product);
    }
}

2-й набор данных не прошел 1 тест для иллюстрации.

0 голосов
/ 14 октября 2011

Я также обнаружил, что вы не можете напрямую связывать поставщиков данных:

class ProviderTest extends PHPUnit_Framework_TestCase {

    public function provider() {
        return array(array('test'));
    }

    /**
     * @dataProvider provider
     */
    public function providerTest1($test) {
        $this->assertTrue($test);
        return array(array($test));
    }

    /**
     * @dataProvider providerTest1
     */
    public function providerTest2($test) {
        $this->assertEquals('test', $test);
    }

}

Очевидно, PHPUnit вызывает все функции поставщика перед выполнением каких-либо тестов, поэтому вы даже не можете использовать отдельные функции поставщика для подачи тестаданные результатов для других испытаний.Лучшее, что вы можете сделать, это симулировать:

class ProviderTest extends PHPUnit_Framework_TestCase {

    private $provider_data = array();

    public function provider() {
        return array(array('test'));
    }

    /**
     * @dataProvider provider
     */
    public function testProvider1($test) {
        $this->assertFalse(empty($test));
        array_push($this->provider_data, array($test));
    }

    /**
     * @depends testProvider1
     */
    public function testProvider2($test = NULL) {
        if(is_null($test)) {
            // simulate a provider
            foreach($this->provider_data as $row) {
                call_user_func_array(array($this, __METHOD__), $row);
            }
        } else {
            $this->assertEquals('test', $test);
        }
    }

}
0 голосов
/ 24 ноября 2010

Удалите параметр из публичной функции testAddStream ($ logger) и попробуйте снова. Я не верю, что PHPUnit вызовет тест, требующий параметров, которые он не может передать.

...