在PHPUnit / DBUnit中关闭外键约束

时间:2012-03-28 08:54:06

标签: unit-testing pdo foreign-keys phpunit dbunit

我正在开发用于测试模型函数的单元测试。

我正在使用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 个答案:

答案 0 :(得分:15)

像这样更改你的功能setUp

protected function setUp() {
   $conn=$this->getConnection();
   $conn->getConnection()->query("set foreign_key_checks=0");
   parent::setUp();
    $conn->getConnection()->query("set foreign_key_checks=1");
}

答案 1 :(得分:4)

感谢@ 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");
    }
}

答案 2 :(得分:1)

有时可能是事先手动截断表格并确保数据集的排序正确,即父表先行,然后是依赖子表格。然后,您可以避免在每次测试时设置foreign_key_checks