2012-02-28 53 views
15

我目前正在爲我的項目使用PHPUnit和DBUnit。我在DBUnit中有一個問題,因爲DBUnit PHPUnit_Extensions_Database_TestCase­Src類似乎不會截斷測試數據庫中的現有數據。所以這使得我的插入測試在僅工作一次後就失敗了。phpunit中的dbunit不會截斷表格

我使用MySQL和這裏是我的代碼:

abstract class Generic_Tests_DatabaseTestCase extends PHPUnit_Extensions_Database_TestCase 
{ 
    // only instantiate pdo once for test clean-up/fixture load 
    static private $pdo = null; 

    // only instantiate PHPUnit_Extensions_Database_DB_IDatabaseConnection once per test 
    private $conn = null; 

    final public function getConnection() 
    { 
     if ($this->conn === null) { 
      if (self::$pdo == null) { 
       self::$pdo = new PDO("mysql:dbname=db;host=localhost", "root", "pass"); 
      } 
      $this->conn = $this->createDefaultDBConnection(self::$pdo, "db"); 
     } 

     return $this->conn; 
    } 
} 

class DbopTest extends Generic_Tests_DatabaseTestCase 
{  
    private $db; 

    protected function setup(){ 
     $this->db = null; 
    } 

    public function getDataSet(){ 
     return $this->createMySQLXMLDataSet(dirname(__FILE__) . '/../rows.xml'); 
    }  
    ... 
} 

那麼如何才能解決這個問題呢?我在這裏做錯了什麼?

+0

希望截斷的地方在哪裏?你使用哪個版本的PHPUnit和哪個版本的DBUnit? – hakre 2012-02-28 22:10:08

+0

多數民衆贊成的問題,我認爲在我的getDataSet方法,截斷操作自動。但我無法看到發生。我正在使用PHP單元3.6.10。 – LostMohican 2012-02-29 11:48:23

+4

這只是一個猜測,但是你覆蓋了'setUp()'方法。請檢查是否仍然調用getDataSet()。 – hakre 2012-02-29 15:04:39

回答

38

如果忽略setUp方法,PHPUnit的不會自動調用getDataSet方法。你需要注意,你也可以調用parent::setUp方法,否則PHPUnit不知道該怎麼做;)。

+1

+1容易錯過。謝謝。 – eddy147 2012-08-02 06:53:46

+0

哈哈哈,謝謝:D – inf3rno 2013-04-18 02:53:41

+3

我不重寫我的測試中的setUp方法,但它仍然不會截斷表。 DBUnit在什麼時候實際截斷了數據庫? – AgmLauncher 2015-08-07 15:39:09

0

您需要有​​方法,否則PHPUnit會假定您沒有數據需要fixturize。

http://www.phpunit.de/manual/3.6/en/database.html

的方法getDataSet()定義瞭如何執行每個試驗前的數據庫的初始狀態應該看。通過由接口PHPUnit_Extensions_Database_DataSet_IDataSet和PHPUnit_Extensions_Database_DataSet_IDataTable表示的概念DataSet和DataTable抽象數據庫的狀態。下一節將詳細介紹這些概念是如何工作的,以及在數據庫測試中使用它們的好處。

對於實現,我們只需要知道在setUp()期間調用getDataSet()方法一次來檢索fixture數據集並將其插入到數據庫中。在這個例子中,我們使用了一個工廠方法createFlatXMLDataSet($ filename),它通過一個XML表示來表示一個數據集。

+0

你可以看到我的DbopTest方法有一個getDataSet方法,它從mysqldump文件創建數據集。 – LostMohican 2012-02-29 11:49:28

3

我自己遇到了這個問題,這是我在挖掘PHPUnit源代碼之後解決的。它看起來像PHPUnit_Extensions_Database_TestCase類的默認行爲是返回PHPUnit_Extensions_Database_Operation_Factory :: NONE()。對於你所需要的,而PHPUnit的文檔似乎怎麼暗示它是如何工作的,你要覆蓋的方法返回PHPUnit_Extensions_Database_Operation_Factory :: TRUNCATE()。

幸運的是,這是相當直接的。您只需將以下內容添加到您的TestCase類。

protected function getTearDownOperation() 
{ 
    return \PHPUnit_Extensions_Database_Operation_Factory::TRUNCATE(); 
} 

在此之前,我在手工拆解我截斷表()方法,但我想你一定會同意這個解決方案要好得多。

1

不奢望過很多榮譽了這個答案,但我已經花了幾個小時試圖找出爲什麼我的測試數據庫表的一個沒有得到截斷,造成上述相同的重複錄入錯誤。我的getDataSet()看起來像

function getDataSet() { 

    $files = array('languages','interpreters','interp_languages', 
     'interp_events','deft_events', 
      //etc 
    ); 

    $dataSets = array(); 
    foreach ($files as $file) { 
     $dataSets[] = new PHPUnit_Extensions_Database_DataSet_MysqlXmlDataSet(
     $this->files_dir."/$file.xml"); 
    } 

    return new PHPUnit_Extensions_Database_DataSet_CompositeDataSet($dataSets); 
} 

並且該技術在其他測試類上正常工作。碰巧我inadvertentely 離開了從$我的XML數據文件名的文件置於其中,因此DbUnit的未加載數據文件,故我不截斷表。但由於有大量來自使用相同的數據文件,其他的測試表中的遺留行的,這一點不明確(我)發生了什麼事。

希望它可以幫助別人避免在某天將她的眼球撕裂。