Has anyone been able to to use Zend_Test_DbAdapter with Zend_Db_Table_Abstract?
I'm trying to test a Model I created that extends Zend_Db_Table_Abstract and I get an exception regarding the primary key not being set if I use a Zend_Test_DbAdapter (other adapters like mysql or sqlite) work fine.
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;
}
}
Snippet from a PHPUnit test class:
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);
}
Exceptions are thrown when exercising the Model's methods:
public function testGetMap()
{
$expected = array(
'1' => 'pranks',
'2' => 'physical_feats',
'3' => 'art',
'4' => 'cute',
'5' => 'philanthropy'
);
$actual = $this->fixture->getMap();
$this->assertEquals($expected, $actual);
}
Results in:
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
Forcing a primary key does not work either:
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'
));
}
Executing the same unit test, from above results in:
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
The reason you are getting the exception
Zend_Db_Table_Exception: A table must have a primary key, but none was found
is because all tables that useZend_Db_Table
must have a primary key defined. When you go to use the table, since a primary key was not defined in yourDbTable
class, Zend_Db attempts to determine the table's primary key by examining the table's properties from the information schema. It sees your table doesn't have a primary key and fails.From the manual:
Trying to force the primary key isn't working because it looks like your table doesn't have a column called
id
which you are specifying as the primary key.The solution would be to add a primary key to the table you are trying to use.
In your model class that extends
Zend_Db_Table_Abstract
you can specify a primary key that isn't ID usingprotected $_primary = 'primary_column';