2

有沒有人能夠使用Zend_Test_DbAdapter與Zend_Db_Table_Abstract?使用zend測試dbadapter與zend數據庫表摘要

我想測試一個我創建的擴展Zend_Db_Table_Abstract的模型,並且如果我使用Zend_Test_DbAdapter(其他適配器,如mysql或sqlite)工作正常,我得到的主鍵未設置異常。


class Model_Category extends Zend_Db_Table_Abstract 
{ 
    protected $_name = 'categories'; 

    protected $_dependentTables = array('Model_Video'); 

    public function getMap() 
    { 
     $map = array(); 
     $rows = $this->fetchAll(); 
     foreach($rows as $row) 
     { 
      $map[$row->id] = $row->name; 
     } 

     return $map; 
    } 
} 

從PHPUnit的測試類片段:

public function testGetMap() 
{ 
    $expected = array(
     '1' => 'pranks', 
     '2' => 'physical_feats', 
     '3' => 'art', 
     '4' => 'cute', 
     '5' => 'philanthropy' 
    ); 
    $actual = $this->fixture->getMap(); 
    $this->assertEquals($expected, $actual); 
} 

結果:

行使模型的方法時

protected function setUp() 
{ 
    $adapter = new Zend_Test_DbAdapter(); 
    $stmt = Zend_Test_DbStatement::createSelectStatement(array(
     array('id' => 1, 'name' => 'pranks'), 
     array('id' => 2, 'name' => 'physical_feats'), 
     array('id' => 3, 'name' => 'art'), 
     array('id' => 4, 'name' => 'cute'), 
     array('id' => 5, 'name' => 'philanthropy') 
    )); 
    $adapter->appendStatementToStack($stmt); 

    $this->fixture = new Model_Category($adapter); 
} 

拋出異常

Model_CategoryTest::testGetMap() 
Zend_Db_Table_Exception: A table must have a primary key, but none was found 
ZendFramework-1.10.6/library/Zend/Db/Table/Abstract.php:876 
ZendFramework-1.10.6/library/Zend/Db/Table/Abstract.php:969 
ZendFramework-1.10.6/library/Zend/Db/Table/Select.php:100 
ZendFramework-1.10.6/library/Zend/Db/Table/Select.php:78 
ZendFramework-1.10.6/library/Zend/Db/Table/Abstract.php:1005 
ZendFramework-1.10.6/library/Zend/Db/Table/Abstract.php:1303 
application/models/Category.php:35 
tests/unit/application/models/CategoryTest.php:90 

強制主鍵不起作用或者:

protected function setUp() 
{ 
    $adapter = new Zend_Test_DbAdapter(); 
    $stmt = Zend_Test_DbStatement::createSelectStatement(array(
     array('id' => 1, 'name' => 'pranks'), 
     array('id' => 2, 'name' => 'physical_feats'), 
     array('id' => 3, 'name' => 'art'), 
     array('id' => 4, 'name' => 'cute'), 
     array('id' => 5, 'name' => 'philanthropy') 
    )); 
    $adapter->appendStatementToStack($stmt); 

    $this->fixture = new Model_Category(array(
     'db' => $adapter, 
     'primary' => 'id' 
    )); 
} 

執行相同的單元測試,從上面的結果:

Model_CategoryTest::testGetMap() 
Zend_Db_Table_Exception: Primary key column(s) (id) are not columns in this table() 
ZendFramework-1.10.6/library/Zend/Db/Table/Abstract.php:888 
ZendFramework-1.10.6/library/Zend/Db/Table/Abstract.php:969 
ZendFramework-1.10.6/library/Zend/Db/Table/Select.php:100 
ZendFramework-1.10.6/library/Zend/Db/Table/Select.php:78 
ZendFramework-1.10.6/library/Zend/Db/Table/Abstract.php:1005 
ZendFramework-1.10.6/library/Zend/Db/Table/Abstract.php:1303 
application/models/Category.php:35 
tests/unit/application/models/CategoryTest.php:93 
+0

你可以發佈你的模型的代碼以及異常的堆棧跟蹤是什麼? – drew010

+0

我已將代碼和痕跡添加到原始文章中。我希望這可以幫助。我應該提及在跟蹤中爲Category.php和CategoryTest.php列出的行號是錯誤的,因爲我壓縮了這篇文章的源代碼。 – Nick

+0

在這兩種情況下,跟蹤都是在Category.php中引用「$ rows = $ this-> fetchAll()」,並且「$ actual = $ this-> fixture-> getMap();」在CategoryTest.php中。 – Nick

回答

0

的原因,你所得到的例外Zend_Db_Table_Exception: A table must have a primary key, but none was found是因爲所有使用Zend_Db_Table的表都必須定義一個主鍵。當您使用表時,由於您的DbTable類中沒有定義主鍵,因此Zend_Db會嘗試通過檢查信息模式中表的屬性來確定表的主鍵。它看到你的表沒有主鍵並失敗。

manual

如果不指定主鍵,Zend_Db_Table_Abstract試圖 發現基於 describeTable()方法中提供的信息的主鍵。

注意:每個表類必須知道哪些列可用於唯一地尋址 行。如果在表 類定義或表構造器參數沒有指定主鍵列,或在通過 ** describeTable()提供的表元數據發現,則該表不能 與Zend_Db_Table使用。

試圖迫使主鍵不工作,因爲它看起來像你的表沒有列名爲id爲其指定作爲主鍵。

解決方法是將主鍵添加到您嘗試使用的表中。

在你的模型類,它擴展Zend_Db_Table_Abstract你可以指定一個主鍵,是不是使用protected $_primary = 'primary_column';

+0

感謝您的迴應!問題是我試圖使用Zend_Test_DbAdapter進行測試。該適配器沒有連接到真正的數據庫,因此沒有表元數據的概念(據我所知)。 – Nick

+0

這是真的,但它延伸自'Zend_Db_Table_Abstract',它在構造的早期執行此檢查,所以這就是爲什麼你會收到錯誤。在測試中,您仍然需要設置一個您在生產中必須執行的主鍵。添加主鍵的定義應該超過錯誤。 – drew010

+0

正如我之前所說的,Zend_Test_DbAdapter沒有元數據的概念,因此沒有列可以被設置爲主鍵。最後,我認爲你回答了我的問題 - 因爲Zend_Db_Table_Abstract需要主鍵,Zend_Test_DbAdapter不能被使用。這是一個恥辱...... – Nick

2

您可以定義這樣做對你Zend_Test_DbAdapter實例如下主鍵ID:

$adapter = new Zend_Test_DbAdapter(); 
$adapter->setDescribeTable('table_name', array('column_name' => 
    array(
     'SCHEMA_NAME' => 'schema_name', 
     'TABLE_NAME' => 'table_name' 
     'COLUMN_NAME' => 'column_name',  
     'PRIMARY'  => true 
    ) 
)); 

然後將table_name,column_name和schema_name與您的實現中的值一起轉換。您需要爲每個與被測試的課程進行交互的表執行此操作。

+0

解決了部分問題,但暴露了一個新的相關問題。當調用Zend_Db_Adapter_Abstract的fetchPairs()方法時,$ row [0]和$ row [1]不存在。這是因爲$ stmt-> fetch(Zend_Db :: FETCH_NUM)仍然返回一個關聯數組,而不是數組數組。 – Nick