phpunit数据库测试而不影响数据库
作者:互联网
我现在正在使用phpunit几天,现在我需要测试数据库查询.我遵循了phpunit官方文档,但我认为我错过了其背后的主要思想.我实现了两个抽象函数getConnection和getDataSet,如下所示:
/**
* @return PHPUnit_Extensions_Database_DB_IDatabaseConnection
*/
public function getConnection()
{
$pdo = new PDO('mysql:host=localhost;dbname=testdb', $this->config['mysql_usr'], $this->config['mysql_pass']);
return $this->createDefaultDBConnection($pdo, 'testdb');
}
/**
* @return PHPUnit_Extensions_Database_DataSet_IDataSet
*/
public function getDataSet()
{
return $this->createXMLDataSet(dirname(__FILE__).'/../dbTest/fixtures/data.xml');
}
好的,现在我正在与我的本地数据库进行交互,但是为什么我需要创建XML数据集(除了比较之外,我还需要它)吗?
我发现自己只与数据库中的数据进行交互.
例如,现在,我想测试一个从数据库中删除的功能:
function deleteRule($id){
$DBH = $this->getDbh();
$query = "SELECT id from ads where group_id=$id";
$STH = $DBH->query($query);
if ($STH->rowCount() > 0){
throw new Exception("Rule has {$STH->rowCount()} ads, can't delete", 400);
} else {
$query = "DELETE FROM rules WHERE id=:id limit 1";
$stmt = $DBH->prepare($query);
$stmt->execute(array(':id' => $id));
}
}
所以我开始为此编写一些测试,其中一个看起来像这样:
public function testDeleteRule_legalDeletion()
{
$id = 3;
$pdo = $this->getConnection();
$fixture = new AdRules();
$fixture->setDbh($pdo);
$res = $fixture->deleteRule($id);
$DBH = $fixture->getDbh();
$query = "SELECT * FROM rules WHERE id=3";
$stmt = $DBH->prepare($query);
$stmt->execute();
$rows = $stmt->rowCount();
$this->assertEquals($rows,0);
}
但是现在,从数据库中删除后,如何将其恢复为初始状态?我知道我可以简单地执行mysql语句,但是我猜想它错过了模拟PDO对象并避免对数据库进行重大更改的所有要点.
无论如何,对此我非常困惑,任何指导将不胜感激.
解决方法:
建议使用其他数据库进行测试,因为您可以说破坏生产数据.当您拥有其他数据库时,可以使用事务机制来测试查询.
如何运作?
>在引导测试中,您应该连接到测试数据库
> PHPUnit调用setUp,该启动在引导程序中创建的数据库句柄上启动新事务
>然后在测试用例(testDeleteRule_legalDeletion)中,修改数据库内容并断言数据与预期的一样
> PHPUnit调用tearDown方法,该方法回滚事务并清理表(用于测试数据库句柄)
因此,对于这些操作,您可能需要一些常规的数据库测试用例,例如DbTransactionalTestCase,在此类中,您必须重写方法setUp和tearDown.
PS.如果您对自动执行此过程的框架感兴趣,请查看我们如何在Ouzo Framework中进行.Here是针对您问题的文档.
标签:phpunit,php,database 来源: https://codeday.me/bug/20191119/2039386.html