简体   繁体   English

带有dbunit的phpunit:如何在测试之间将数据保留在db中?

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

i have a phpunit question regarding dbunit and how to keep data created in the database by one test for use in the next. 我有一个关于dbunit的phpunit问题,以及如何保留一项测试在数据库中创建的数据以供下次使用。 i'm new to phpunit (we've been using an in-house tester for years but are finally trying to get with the modern age), so i apologize if this is a trivial issue. 我是phpunit的新手(我们多年来一直在使用内部测试仪,但最终还是试图与现代时代接轨),因此,如果这是一个小问题,我深表歉意。

the desired effect i have a mysql table that contains a column that is a unique key. 想要的效果,我有一个mysql表,其中包含一个唯一键列。 if an attempt is made to insert a duplicate of this column, special things happen that i would like to be able to test. 如果尝试插入此列的重复项,则会发生一些我想测试的特殊事件。 i have written a test to insert a value into this column (and test its success) and then written another test immediately afterwards to test how the class fails on attempting a duplicate value. 我编写了一个将值插入此列的测试(并测试其是否成功),然后立即编写了另一个测试,以测试该类在尝试重复值时如何失败。 i'd like to be able to catch that exception and test it. 我希望能够捕获该异常并对其进行测试。 i am using dbunit to pre-fill my db with all the pre-filly stuff i need. 我正在使用dbunit将我需要的所有预填充内容预填充到db中。

the problem at the commencement of each test it appears as if getDataSet() is called and, as a result, the unique key data i insert in the first test is no longer there to test against. 每次测试开始时出现问题 ,就好像调用了getDataSet()一样,结果,我在第一个测试中插入的唯一密钥数据不再在那里可以进行测试。 consequently, i can't test the anticipated failure of inserting duplicate unique keys. 因此,我无法测试插入重复的唯一键的预期失败。

what i'm looking for well, obviously some way to persist the database data across tests; 我正在寻找的东西 ,显然是某种在测试之间持久保存数据库数据的方法; avoid calling getDataSet(), perhaps, at the beginning of the second test. 避免在第二个测试开始时调用getDataSet()。

i certainly hope this is possible. 我当然希望这是可能的。 i can't imagine why it wouldn't be; 我无法想象为什么不会。 it seems like people should want to test duplicate insert! 似乎人们应该测试重复的插入! i am willing to entertain other solutions if they accomplish the task. 如果他们完成任务,我愿意接受其他解决方案。

thanks in advance! 提前致谢!

here's my test, stripped down to the relevant bits. 这是我的测试,简化为相关内容。

<?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 

}

The fact that each test runs independently from others is a feature and a design goal of unit testing. 每个测试都独立运行的事实是单元测试的功能和设计目标。

In your case you can simply use this: 您可以使用以下方法:

/**
 * 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");
}

Please note the usage of @expectedException which simplifies the test code a lot. 请注意@expectedException的用法,它大大简化了测试代码。 However, I would write my code in a way that it throws a DuplicateKeyException , this would make the test more specific. 但是,我将以抛出DuplicateKeyException的方式编写代码,这将使测试更加具体。 In the current form, you would for example not being able to detect a database connection error anymore (and the test would succeed!). 在当前形式中,例如,您将不再能够检测数据库连接错误(并且测试将成功!)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM