与dbunit的phpunit:如何在测试中保存数据库中的数据?

时间:2015-08-01 04:24:07

标签: php testing phpunit

我有一个关于dbunit的phpunit问题,以及如何通过一次测试将数据保存在数据库中以供下一次使用。我是phpunit的新手(我们多年来一直在使用内部测试人员,但最终还是试图适应现代时代),所以如果这是一个微不足道的问题我会道歉。

期望的效果 我有一个mysql表,其中包含一个唯一键的列。如果试图插入此列的副本,我希望能够测试的特殊事情发生。我编写了一个测试,在这个列中插入一个值(并测试它的成功),然后立即编写另一个测试来测试类在尝试重复值时如何失败。我希望能够捕获该异常并进行测试。我正在使用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 

}

1 个答案:

答案 0 :(得分:1)

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

在你的情况下你可以简单地使用它:

/**
 * 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的方式编写我的代码,这会使测试更具体。在当前形式中,您将不再能够检测到数据库连接错误(并且测试将成功!)。