PhpRiot
News Archive
Related Articles
PhpRiot Newsletter
Your Email Address:

More information

Learning lessons at ZendUncon

Note: This article was originally published at Planet PHP on 13 November 2012.
Planet PHP
In my previous post I already mentionedASebastian Jerzy WilczyAski (@dj_sebastian_w) and his uncon session "Unit Testing for Databases using fixtures and phpunit". It made me wonder how much difference it would make if you use fixtures instead of testing database interactions using predefined sets of data.

Since I work a lot with Zend Framework I was looking at how I could use fixtures and mock objects to follow Sebastian's guidelines. So I gave it a try. This is what I came up with.

I use the domain model design pattern for accessing data storages with Zend Framework so this means I have a model (Order_Model_Order) which is the representation of my data object, a mapper (Order_Model_OrderMapper) to connect my model with an underlying data storage backend and a table gateway object (Order_Model_DbTable_Order) to link everything to the database. The object we're going to focus on is Order_Model_OrderMapper as this is the link that connects my model to the database.

At first I start my test class with fixtures.


class Order_Model_OrderMapperTest extends PHPUnit_Framework_TestCase
{
protected $_order = array (
0 = array (
'id' = 1,
'status' = 0,
'price' = 2499.95,
'currency' = 'USD',
'exchange_rate' = 1.2714,
'vat_id' = 3,
'vat_percentage' = 0.00,
'created_by' = 400,
'created_at' = '2012-02-29 10:11:12',
'updated_by' = 303,
'updated_at' = '2012-11-04 03:01:01',
),
1 = array (
'id' = 1,
'status' = 0,
'price' = 10000.00,
'currency' = 'EUR',
'exchange_rate' = 1.00,
'vat_id' = 1,
'vat_percentage' = 21.00,
'created_by' = 400,
'created_at' = '2012-02-29 10:11:12',
'updated_by' = 303,
'updated_at' = '2012-11-04 03:01:01',
),
);
}

The next thing we need to come up with is how to mock out the data gateway as we don't want to connect to the database of course. Because my mapper class Order_Model_OrderMapper has 2 methods to set and retrieve the data gateway it's easy to flip in and out the data gateway object. Here's my Order_Model_OrderMapper class:

class Order_Model_OrderMapper
{
/**
* @var Zend_Db_Table_Abstract
*/
protected $_dbTable;
/**
* Sets the data gateway for this Mapper class
*
* @param Zend_Db_Table $dbTable
* @throws In2it_Model_Exception
*/
public function setDbTable($dbTable)
{
if (is_string($dbTable)) {
if (!class_exists($dbTable)) {
throw new In2it_Model_Exception(
'Non-existing data gateway provided'
);
}
$dbTable = new $dbTable;
}
if (!$dbTable instanceof Zend_Db_Table_Abstract) {
throw new In2it_Model_Exception('Invalid data gateway provided');
}
$this-_dbTable = $dbTable;
}
/**
* Retrieves the data gateway class from this Mapper class
*
* @return Zend_Db_Table
* @throws In2it_Model_Exception
*/
public function getDbTable()
{
if (!isset ($this-_dbTable)) {
throw new In2it_Model_Exception('Data gateway not set');
}
return $this-_dbTable;
}

...
}

All we need to do now is create a mock object that we can inject in our mapper test so we don't need to connect to the database in order to test our mapper logic.

"/

Truncated by Planet PHP, read more at the original (another 1448 bytes)