需要在每次测试之前使用PHPUnit&清除多个数据库。 DbUnit的

时间:2011-11-24 19:59:27

标签: phpunit dbunit

我正在为连接多个数据库的系统编写测试。我选择将MySQL用于我的测试数据库,即test_database1和test_database2,我通过将生产模式转储到相应的表中来创建。请注意,此时我不需要任何数据,只需要模式。

在运行测试之前,让这些数据库清除的最佳方法是什么?我有两个要求:

  1. 有一些外键约束阻止我只能进行TRUNCATE,所以我需要“手动”清除每个表。
  2. 我需要清除两个数据库。
  3. 我看着压倒一切:

    class PHPUnit_Extensions_Database_Operation_Truncate implements PHPUnit_Extensions_Database_Operation_IDatabaseOperation
    

    在DbUnit中但它似乎依赖于DataSet内容,在我的情况下它将是空的,因为我通过mysqldump --no-data预加载我的模式。

    任何指针?

3 个答案:

答案 0 :(得分:0)

您可以创建一个实用程序函数来重建数据库,该数据库可以在需要干净数据库的测试之前调用,也可以在setUp()函数中调用:

class DbUtil {

    public static function rebuild($src, $dest) {
        exec("mysql -u someuser -p password -e 'DROP DATABASE $dest'");
        exec("mysql -u someuser -p password -e 'CREATE DATABASE $dest'");
        exec("mysqldump -d -u someuser -p password $src > mysql -u someuser -p password $dest");
    }
}

class MyTest extends PHPUnit_Framework_TestCase {

    protected function setUp() {
        DbUtil::rebuild('prod_database1', 'test_database1');
        DbUtil::rebuild('prod_database2', 'test_database2');
    }

    // ...
}

这可能不是最高效的方法,但每次测试都会得到一个干净的数据库。

如果您愿意或可以从MySQL切换到您的测试,我已成功构建模板sqlite数据库文件并将该文件复制到其他位置进行测试。每个测试都使用干净的模板文件覆盖测试数据库文件。

注意:Exec命令仅出于演示目的而编写,尚未针对确切的开关/参数进行测试。

答案 1 :(得分:0)

我使用带有灯具的标准PHPUnit_DatabaseTestCase来实现

protected $_connectionMock;
protected $_secondDbConnectionMock;

protected $backupGlobalsBlacklist = array('application');  // btw this hack will speed up your tests

/**
 * @return Zend_Test_PHPUnit_Db_Connection
 */
protected function getConnection()
{
    if ($this->_connectionMock == null) {
        $multiDb = Zend_Registry::get('multidb');

        $connection = $multiDb->getDb();

        $this->_connectionMock = $this->createZendDbConnection(
            $connection, ''
        );

        Zend_Db_Table_Abstract::setDefaultAdapter($connection);
    }
    return $this->_connectionMock;
}

protected function getSecondDbConnection()
{
    if ($this->_dnsConnectionMock == null) {
        $multiDb = Zend_Registry::get('multidb');

        $connection = $multiDb->getDb('second_db');

        $this->_secondDbConnectionMock = $this->createZendDbConnection(
            $connection, ''
        );
    }

    return $this->_dnsConnectionMock;
}

protected function setUp()
{
    parent::setUp();

    $this->databaseTester = NULL;

    $this->getDatabaseTester()->setSetUpOperation($this->getSetUpOperation());
    $this->getDatabaseTester()->setDataSet($this->getDataSet());
    $this->getDatabaseTester()->onSetUp();

    $secondDataSet = $this->getDataSetForSecondDb();
    if ($dnsDataSet) {
        // create data set for second db
        $secondDataTester = new PHPUnit_Extensions_Database_DefaultTester($this->getSecondDbConnection());
        $secondDataTester->setSetUpOperation($this->getSetUpOperation());
        $secondDataTester->setDataSet($secondDataSet);
        $secondDataTester->onSetUp();
    }

}

protected function getDataSetForSecondDb()
{
    return null;
}

}

但是为了使用multidb

我扩展了它

答案 2 :(得分:-1)

我发现更好solution here 将外键检查设置为0