Установите ограничения внешнего ключа в PHPUnit / DBUnit - PullRequest
11 голосов
/ 28 марта 2012

Я разрабатываю модульные тесты для тестирования функций модели.

Я использую PHP PDO с DBUnit 1.1.2 и PHPUnit 3.6.10, и мой набор данных представляет собой файл yml.

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

Ниже приведен фрагмент (не весь файл класса) кода в моем обобщенном файле Testcase, который я буду включать для любого нового тестового примера, который я разрабатываю.

Когда я запускаю тестовый пример с этими настройками, эти настройки я обнаружил, что $ pdo-> exec () не выполняется.

Что не так с моим подходом? Есть ли лучшая альтернатива?

class MyTestCase extends PHPUnit_Extensions_Database_TestCase {

public function getConnection() {
  $this->pdo = $this->getPDO();

  echo "BEFORE FOREIGN KEY QUERY\n";
  $conn =  $this->createDefaultDBConnection($this->pdo, 'my-schema');
  $this->pdo->exec("set foreign_key_checks=0");

  return $conn;
}

private function getPDO() {
  include BASEPATH . '/application/config/database.php';
  $dbt = $db['testing'];
  $conn_string = sprintf("%s:host=%s;dbname=%s", $dbt['dbdriver'], $dbt['hostname'],     $dbt['database']);
  $pdo = new PDO($conn_string, $dbt['username'], $dbt['password']);
  return $pdo;
}

public function getDataSet() {
  echo "BEFORE FOREIGN KEY QUERY in getDataSet\n";
  $this->pdo->exec("set foreign_key_checks=1");
  return new PHPUnit_Extensions_Database_DataSet_YamlDataSet(ROOTPATH."/application/tests/data/my-dataset.yml");
}

public function setUp() {
   parent::setUp();
}

Ответы [ 3 ]

16 голосов
/ 11 июня 2013

Измените настройку вашей функции следующим образом

protected function setUp() {
   $conn=$this->getConnection();
   $conn->getConnection()->query("set foreign_key_checks=0");
   parent::setUp();
    $conn->getConnection()->query("set foreign_key_checks=1");
}
4 голосов
/ 02 июня 2016

Благодаря комментариям @ user2045006 и @marcini я создал решение для своего проекта ниже.

class MyDbTestCase extends PHPUnit_Extensions_Database_TestCase
{
    protected function getConnection()
    {
        // ... as normal ...
    }

    protected function getSetUpOperation()
    {
        // Override
        return new PHPUnit_Extensions_Database_Operation_Composite([
            PHPUnit_Extensions_Database_Operation_Factory::TRUNCATE(),
            new InsertOperationWithoutFkChecks(),
        ]);
    }

}

// Custom subclass
class InsertOperationWithoutFkChecks extends PHPUnit_Extensions_Database_Operation_Insert
{
    public function execute(
        PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection,
        PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet
    ) {
        $connection->getConnection()->exec("SET foreign_key_checks = 0");
        parent::execute($connection, $dataSet);
        $connection->getConnection()->exec("SET foreign_key_checks = 1");
    }
}
1 голос
/ 12 сентября 2013

Иногда это может быть случай предварительного усечения таблиц вручную и обеспечения правильного упорядочения набора данных, т.е. сначала родительской таблицы, а затем зависимых дочерних таблиц.Затем вы можете избежать установки foreign_key_checks для каждого теста

...