带有 dbunit 的 phpunit:如何跨测试将数据保存在我的数据库中?

phpunit with dbunit: how can i keep data in my db across tests?

我有一个关于 dbunit 的 phpunit 问题,以及如何保存一个测试在数据库中创建的数据以供下一个测试使用。我是 phpunit 的新手(多年来我们一直在使用内部测试仪,但最终试图适应现代),所以如果这是一个微不足道的问题,我深表歉意。

想要的效果 我有一个 mysql table,其中包含一个作为唯一键的列。如果尝试插入此列的副本,则会发生我希望能够测试的特殊情况。我已经编写了一个测试来将一个值插入该列(并测试它是否成功),然后立即编写另一个测试来测试 class 在尝试重复值时如何失败。我希望能够捕获该异常并对其进行测试。我正在使用 dbunit 将我需要的所有预填充内容预填充到我的数据库中。

问题 在每次测试开始时,似乎调用了 getDataSet(),因此,我在第一个测试中插入的唯一关键数据不再用于测试。因此,我无法测试插入重复唯一键的预期失败。

我在找什么 好吧,显然有一些方法可以跨测试持久保存数据库数据;避免在第二次测试开始时调用 getDataSet()。

我当然希望这是可能的。我无法想象为什么不会;似乎人们应该想要测试重复插入!如果他们完成任务,我愿意接受其他解决方案。

提前致谢!

这是我的测试,精简到相关部分。

<?php
class UserPOSTTest extends \PHPUnit_Extensions_Database_TestCase
{

    static private $pdo = null;
    private $conn = null;

    /**
     * @return PHPUnit_Extensions_Database_DB_IDatabaseConnection
     */
    public function getConnection()
    {
        if($this->conn === null) {
            if (self::$pdo == null) {
                self::$pdo = new \PDO('mysql:host=localhost;dbname=thedatabase', 'user', '*********');
            }
            $this->conn = $this->createDefaultDBConnection(self::$pdo, "db");
        }
        return $this->conn;
    }

    /**
     * @return PHPUnit_Extensions_Database_DataSet_IDataSet
     */
    public function getDataSet()
    {
        // this is returned at the beginning of every test
        return $this->createFlatXmlDataSet(dirname(__FILE__) . '/some_data_set.xml');
    }

    /**
     * test the insertion of the value "unique key value" into a column set as UNIQUE KEY in mysql
     * since getDataSet() has cleared this table, it passes.
     */
    public function uniqueKeyTest_passes() 
    {
        $inserter = new Inserter("unique key value");

        $this->assertEquals($inserter->one,1); // just some bogus assertion 

    } // uniqueKeyTest_passes

    /**
     * run the exact same insert as in uniqueKeyTest_passes() above. the purpose of this test is to
     * confirm how the Inserter class fails on the attempt to insert duplicate data into a UNIQUE KEY column.
     * however, the data inserted in uniqueKeyTest_passes() has been scrubbed out by getDataSet()
     * this is the crux of my question
     */
    public function uniqueKeyTest_should_fail() 
    {
        try {
            // exact same insert as above, should fail as duplicate
            $inserter = new Inserter("unique key value");
        }
        catch(Exception $e) {
            // if an exception is thrown, that's a pass
            return;
        }

        // the insert succeeds when it should not
        $this->fail("there should be an exception for attempting insert of unique key value here");

    } // uniqueKeyTest_should_fail 

}

每个测试独立于其他测试运行这一事实是单元测试的一个特征和设计目标。

在你的情况下,你可以简单地使用这个:

/**
 * Confirm how the Inserter class fails on the attempt to 
 * insert duplicate data into a UNIQUE KEY column.
 * 
 * @expectedException Exception
 */
public function uniqueKeyTest_should_fail() 
{
    $inserter = new Inserter("unique key value");
    // exact same insert as above, should fail as duplicate
    $inserter = new Inserter("unique key value");
}

请注意@expectedException的用法,它大大简化了测试代码。但是,我会以抛出 DuplicateKeyException 的方式编写我的代码,这将使测试更加具体。例如,在当前形式中,您将无法再检测到数据库连接错误(并且测试会成功!)。