Dbunit в phpunit не обрезает таблицы

В настоящее время я использую PHPUnit и DBUnit для своего проекта. У меня проблема с DBUnit, потому что класс DBUnit PHPUnit_Extensions_Database_TestCase & shy; Src, похоже, не обрезает существующие данные на тестовом db. Поэтому это приводит к тому, что мои тесты на вставку терпят неудачу после работы только один раз.

Я использую mysql, и вот мой код:

abstract class Generic_Tests_DatabaseTestCase extends PHPUnit_Extensions_Database_TestCase
{
    // only instantiate pdo once for test clean-up/fixture load
    static private $pdo = null;

    // only instantiate PHPUnit_Extensions_Database_DB_IDatabaseConnection once per test
    private $conn = null;

    final public function getConnection()
    {
        if ($this->conn === null) {
            if (self::$pdo == null) {
                self::$pdo = new PDO( "mysql:dbname=db;host=localhost", "root", "pass" );
            }
            $this->conn = $this->createDefaultDBConnection(self::$pdo, "db");
        }

        return $this->conn;
    }
}

class DbopTest extends Generic_Tests_DatabaseTestCase
{       
    private $db;

    protected function setup(){
        $this->db = null;
    }

    public function getDataSet(){
        return $this->createMySQLXMLDataSet(dirname(__FILE__) . '/../rows.xml');
    }       
    ...
}

Итак, как я могу исправить эту проблему? Что я здесь делаю неправильно?

Ответы

Ответ 1

Если вы переопределите метод setUp, PHPUnit автоматически не вызовет ваш метод getDataSet. Вам нужно позаботиться о том, чтобы вы вызывали метод parent::setUp, иначе PHPUnit не знает, что делать;).

Ответ 2

Я сам столкнулся с этой проблемой, и именно так я решил ее после небольшого перекопать в исходный код PHPUnit. Похоже, что поведение по умолчанию для класса PHPUnit_Extensions_Database_TestCase заключается в возврате PHPUnit_Extensions_Database_Operation_Factory:: NONE(). Для того, что вам нужно, и как, как представляется, PHPUnit-документ подразумевает, как он должен работать, вы захотите переопределить метод для возврата PHPUnit_Extensions_Database_Operation_Factory:: TRUNCATE().

К счастью, это довольно прямолинейно. Вам просто нужно добавить следующее в свой класс TestCase.

protected function getTearDownOperation()
{
    return \PHPUnit_Extensions_Database_Operation_Factory::TRUNCATE();
}

До этого я вручную обрезал таблицы в методе Teardown(), но я думаю, вы согласитесь, что это решение намного лучше.

Ответ 3

Не ожидая слишком большого вознаграждения за этот ответ, но я потратил несколько часов, пытаясь понять, почему одна из моих тестовых таблиц базы данных не усекалась, вызывая такую ​​же повторяющуюся ошибку входа, описанную выше. Мой getDataSet() выглядел как

function getDataSet() {

    $files = array('languages','interpreters','interp_languages',
        'interp_events','deft_events',
           //etc
    );

    $dataSets = array();
    foreach ($files as $file) {
        $dataSets[] = new PHPUnit_Extensions_Database_DataSet_MysqlXmlDataSet(
         $this->files_dir."/$file.xml");
    }

    return new PHPUnit_Extensions_Database_DataSet_CompositeDataSet($dataSets);
}

и этот метод отлично работал на других тестовых классах. Бывает так, что я случайно выбрал одно из своих имен файлов XML файлов из $files, поэтому DbUnit не загружал этот файл данных, а не обрезал таблицу. Но поскольку в таблице было много строк, оставшихся в таблице из других тестов, которые использовали тот же файл данных, мне не было очевидно, что происходит.

Надеюсь, что когда-нибудь он кого-нибудь спасет от разрывания глазных глаз.

Ответ 4

У вас должен быть метод getDataSet(), иначе PHPUnit предполагает, что у вас нет данных для fixturize.

http://www.phpunit.de/manual/3.6/en/database.html

Метод getDataSet() определяет, как должно выглядеть исходное состояние базы данных перед каждым тестом. Состояние базы данных абстрагируется с помощью концепций DataSet и DataTable, которые представлены интерфейсами PHPUnit_Extensions_Database_DataSet_IDataSet и PHPUnit_Extensions_Database_DataSet_IDataTable. В следующем разделе будет подробно описано, как эти понятия работают и какие преимущества для их использования при тестировании базы данных.

Для реализации нам нужно только знать, что метод getDataSet() вызывается один раз во время setUp() для извлечения набора данных прибора и вставки его в базу данных. В этом примере мы используем метод factory createFlatXMLDataSet ($ filename), который представляет собой набор данных через представление XML.