在 PHPUnit/DBUnit 中设置外键约束
Posted
技术标签:
【中文标题】在 PHPUnit/DBUnit 中设置外键约束【英文标题】:Set foreign key constraints off in PHPUnit/DBUnit 【发布时间】:2012-04-11 20:17:30 【问题描述】:我正在开发用于测试模型功能的单元测试。
我正在使用带有 DBUnit 1.1.2 和 phpUnit 3.6.10 的 PHP PDO,我的数据集是一个 yml 文件。
在将灯具加载到数据库中时,我需要关闭外键检查。之后我需要再次打开它,以便我可以在这些限制下运行我的测试。
下面是我的通用测试用例文件中的一个 sn-p(不是整个类文件)代码,我将包含在我开发的任何新测试用例中。
当我在这些设置下运行测试用例时,我发现 $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();
【问题讨论】:
我也想要一个更好的解决方案。但这应该工作 更好的解决方案在这里:***.com/questions/10331445/… 【参考方案1】:像这样改变你的函数设置
protected function setUp()
$conn=$this->getConnection();
$conn->getConnection()->query("set foreign_key_checks=0");
parent::setUp();
$conn->getConnection()->query("set foreign_key_checks=1");
【讨论】:
这可能以前有效,但不再有效。当 DBUnit 截断一个表时,它也会禁用检查,然后在完成时重新启用它。所以检查总是在任何插入之前重新启用。 我找到了完成此操作的确切位置:Truncate.php。如果您需要保留旧版本 phpunit 的行为,则需要扩展默认的截断操作类,类似于以下方式:***.com/a/10331869/1844362,并做相反的事情:截断时不要触摸外键。这将使您能够以自己的方式禁用外键并在需要时重新启用。【参考方案2】:感谢@user2045006 和@marcini 的cmets,我为我的项目创建了以下解决方案。
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");
【讨论】:
【参考方案3】:有时可能需要事先手动截断表并确保数据集的顺序正确,即首先是父表,然后是依赖子表。然后,您可以避免在每个测试中设置 foreign_key_checks
【讨论】:
以上是关于在 PHPUnit/DBUnit 中设置外键约束的主要内容,如果未能解决你的问题,请参考以下文章