Zend Framework:我应该如何在 Zend_Db 中对我的 Mapper 进行单元测试?
我将如何在 Zend_Db 中测试我的映射器? 我的每个模型都有 3 个类:
- 模型
- 映射器
- DbTable
这是我的单元测试:
<?php
// Call Model_BugTest::main() if this source file is executed directly.
if (!defined("PHPUnit_MAIN_METHOD")) {
define("PHPUnit_MAIN_METHOD", "Model_ArtistTest::main");
}
require_once dirname(__FILE__) . '/../../TestHelper.php';
/** Model_Artist */
require_once 'Artist.php';
/**
* Test class for Model_Artist.
*
* @group Models
*/
class Model_ArtistTest extends PHPUnit_Framework_TestCase
{
/**
* Runs the test methods of this class.
*
* @return void
*/
public static function main()
{
$suite = new PHPUnit_Framework_TestSuite("Model_ArtistTest");
$result = PHPUnit_TextUI_TestRunner::run($suite);
}
/**
* Sets up the fixture, for example, open a network connection.
* This method is called before a test is executed.
*
* @return void
*/
public function setUp()
{
$this->model = new Ly_Model_Artist();
}
/**
* Tears down the fixture, for example, close a network connection.
* This method is called after a test is executed.
*
* @return void
*/
public function tearDown()
{
}
public function testCanDoTest()
{
$this->assertTrue(true);
}
public function testCanFindArtist()
{
$artist = "Rage Against the Machine";
$result = $this->model->findbyalpha($artist);
var_dump($result);
}
}
我正在使用 Matthew 的 TestHelper: http://github.com/weierophinney/bugapp/blob/master/tests/TestHelper.php
我得到的错误是这样的:
c:\xampp\htdocs\ly\tests>phpunit --configuration phpunit.xml
PHPUnit 3.4.10 by Sebastian Bergmann.
.
Fatal error: Class 'Ly_Model_ArtistMapper' not found in C:\xampp\htdocs\ly\appli
cation\models\Artist.php on line 72
似乎映射器没有被读。谁能告诉我如何进行此类测试?我是单元测试的新手,我才刚刚开始学习它。
这是我的艺术家模型
<?php
/**
* Artist Model
*/
class Ly_Model_Artist
{
protected $_id; //a field
protected $_name; //a field
protected $_mapper;
public function __construct(array $options = null)
{
if (is_array($options)) {
$this->setOptions($options);
}
}
public function __set($name, $value)
{
$pieces = explode('_', $name);
foreach($pieces AS $key => $row) {
$pieces[$key] = ucfirst($row);
}
$name = implode('',$pieces);
$method = 'get' . $name;
if (('mapper' == $name) || !method_exists($this, $method)) {
throw new Exception('Invalid group property');
}
$this->$method($value);
}
public function __get($name)
{
$pieces = explode('_', $name);
foreach($pieces AS $key => $row) {
$pieces[$key] = ucfirst($row);
}
$name = implode('',$pieces);
$method = 'get' . $name;
if (('mapper' == $name) || !method_exists($this, $method)) {
throw new Exception('Invalid group property');
}
return $this->$method();
}
public function setOptions(array $options)
{
$methods = get_class_methods($this);
foreach ($options as $key => $value) {
$method = 'set' . ucfirst($key);
if (in_array($method, $methods)) {
$this->$method($value);
}
}
return $this;
}
public function setMapper($mapper)
{
$this->_mapper = $mapper;
return $this;
}
public function getMapper()
{
if (null === $this->_mapper) {
$this->setMapper(new Ly_Model_ArtistMapper());
}
return $this->_mapper;
}
public function setId($id)
{
$this->_id = (int) $id;
return $this;
}
public function getId()
{
return $this->_id;
}
public function setName($text)
{
$this->_name = (string) $text;
return $this;
}
public function getName()
{
return $this->_name;
}
public function find($id)
{
$this->getMapper()->find($id, $this);
return $this;
}
public function findbyalpha($keyword)
{
return $this->getMapper()->findbyalpha($keyword);
}
}
这是艺术家映射器:
<?php
/**
* Artist Model Mapper
*/
class Ly_Model_ArtistMapper
{
protected $_dbTable;
public function setDbTable($dbTable)
{
if (is_string($dbTable)) {
$dbTable = new $dbTable();
}
if (!$dbTable instanceof Zend_Db_Table_Abstract) {
throw new Exception('Invalid table data gateway provided');
}
$this->_dbTable = $dbTable;
return $this;
}
public function getDbTable()
{
if (null === $this->_dbTable) {
$this->setDbTable('Ly_Model_DbTable_Artist');
}
return $this->_dbTable->getAdapter();
}
public function find($id, Ly_Model_Artist $artist)
{
if(!isset($id) OR empty($id)) {
throw new Exception ('Could not find id.');
}
$result = $this->getDbTable()->find($id);
if (0 == count($result)) {
return;
}
$row = $result->current();
$artist->setId($row->id)
->setName($row->name);
}
public function findbyalpha($keyword)
{
if(!isset($keyword) OR empty($keyword)) {
throw new Exception ('Could not find keyword.');
}
$keyword = $this->getDbTable()->quote($keyword.'%');
//$sql = $this->getDbTable()->select()->where('twitter_id = ?',$twitter_id)->order('weight');
$sql = "SELECT
DISTINCT
a.name
FROM artist a
WHERE a.name LIKE ".$keyword."
ORDER BY a.name ASC
";
//Zend_Debug::dump($sql);
$result = $this->getDbTable()->fetchAll($sql);
return $result;
}
}
Db_Table 看起来像这样:
<?php
class Ly_Model_DbTable_Artist extends Zend_Db_Table_Abstract
{
protected $_name = 'artist';
}
How would I test my mappers in Zend_Db?
Each of my model will have 3 classes:
- The Model
- The Mapper
- The DbTable
Here is my Unit Test:
<?php
// Call Model_BugTest::main() if this source file is executed directly.
if (!defined("PHPUnit_MAIN_METHOD")) {
define("PHPUnit_MAIN_METHOD", "Model_ArtistTest::main");
}
require_once dirname(__FILE__) . '/../../TestHelper.php';
/** Model_Artist */
require_once 'Artist.php';
/**
* Test class for Model_Artist.
*
* @group Models
*/
class Model_ArtistTest extends PHPUnit_Framework_TestCase
{
/**
* Runs the test methods of this class.
*
* @return void
*/
public static function main()
{
$suite = new PHPUnit_Framework_TestSuite("Model_ArtistTest");
$result = PHPUnit_TextUI_TestRunner::run($suite);
}
/**
* Sets up the fixture, for example, open a network connection.
* This method is called before a test is executed.
*
* @return void
*/
public function setUp()
{
$this->model = new Ly_Model_Artist();
}
/**
* Tears down the fixture, for example, close a network connection.
* This method is called after a test is executed.
*
* @return void
*/
public function tearDown()
{
}
public function testCanDoTest()
{
$this->assertTrue(true);
}
public function testCanFindArtist()
{
$artist = "Rage Against the Machine";
$result = $this->model->findbyalpha($artist);
var_dump($result);
}
}
I am using Matthew's TestHelper: http://github.com/weierophinney/bugapp/blob/master/tests/TestHelper.php
The error I get is this:
c:\xampp\htdocs\ly\tests>phpunit --configuration phpunit.xml
PHPUnit 3.4.10 by Sebastian Bergmann.
.
Fatal error: Class 'Ly_Model_ArtistMapper' not found in C:\xampp\htdocs\ly\appli
cation\models\Artist.php on line 72
Seems like the Mapper is not being read. Can anyone show me how to do this kind of testing? I am new to UnitTesting and I am just starting to learn it.
This is my Artist Model
<?php
/**
* Artist Model
*/
class Ly_Model_Artist
{
protected $_id; //a field
protected $_name; //a field
protected $_mapper;
public function __construct(array $options = null)
{
if (is_array($options)) {
$this->setOptions($options);
}
}
public function __set($name, $value)
{
$pieces = explode('_', $name);
foreach($pieces AS $key => $row) {
$pieces[$key] = ucfirst($row);
}
$name = implode('',$pieces);
$method = 'get' . $name;
if (('mapper' == $name) || !method_exists($this, $method)) {
throw new Exception('Invalid group property');
}
$this->$method($value);
}
public function __get($name)
{
$pieces = explode('_', $name);
foreach($pieces AS $key => $row) {
$pieces[$key] = ucfirst($row);
}
$name = implode('',$pieces);
$method = 'get' . $name;
if (('mapper' == $name) || !method_exists($this, $method)) {
throw new Exception('Invalid group property');
}
return $this->$method();
}
public function setOptions(array $options)
{
$methods = get_class_methods($this);
foreach ($options as $key => $value) {
$method = 'set' . ucfirst($key);
if (in_array($method, $methods)) {
$this->$method($value);
}
}
return $this;
}
public function setMapper($mapper)
{
$this->_mapper = $mapper;
return $this;
}
public function getMapper()
{
if (null === $this->_mapper) {
$this->setMapper(new Ly_Model_ArtistMapper());
}
return $this->_mapper;
}
public function setId($id)
{
$this->_id = (int) $id;
return $this;
}
public function getId()
{
return $this->_id;
}
public function setName($text)
{
$this->_name = (string) $text;
return $this;
}
public function getName()
{
return $this->_name;
}
public function find($id)
{
$this->getMapper()->find($id, $this);
return $this;
}
public function findbyalpha($keyword)
{
return $this->getMapper()->findbyalpha($keyword);
}
}
This is the Artist Mapper:
<?php
/**
* Artist Model Mapper
*/
class Ly_Model_ArtistMapper
{
protected $_dbTable;
public function setDbTable($dbTable)
{
if (is_string($dbTable)) {
$dbTable = new $dbTable();
}
if (!$dbTable instanceof Zend_Db_Table_Abstract) {
throw new Exception('Invalid table data gateway provided');
}
$this->_dbTable = $dbTable;
return $this;
}
public function getDbTable()
{
if (null === $this->_dbTable) {
$this->setDbTable('Ly_Model_DbTable_Artist');
}
return $this->_dbTable->getAdapter();
}
public function find($id, Ly_Model_Artist $artist)
{
if(!isset($id) OR empty($id)) {
throw new Exception ('Could not find id.');
}
$result = $this->getDbTable()->find($id);
if (0 == count($result)) {
return;
}
$row = $result->current();
$artist->setId($row->id)
->setName($row->name);
}
public function findbyalpha($keyword)
{
if(!isset($keyword) OR empty($keyword)) {
throw new Exception ('Could not find keyword.');
}
$keyword = $this->getDbTable()->quote($keyword.'%');
//$sql = $this->getDbTable()->select()->where('twitter_id = ?',$twitter_id)->order('weight');
$sql = "SELECT
DISTINCT
a.name
FROM artist a
WHERE a.name LIKE ".$keyword."
ORDER BY a.name ASC
";
//Zend_Debug::dump($sql);
$result = $this->getDbTable()->fetchAll($sql);
return $result;
}
}
And the Db_Table just looks like this:
<?php
class Ly_Model_DbTable_Artist extends Zend_Db_Table_Abstract
{
protected $_name = 'artist';
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
更改映射器以使用控制反转模式(将数据库表对象插入构造函数(至少可选),这样您就可以断开它并传入模拟/存根对象。
Change the mapper to use the Inversion of Control pattern (insert the DB Table Object into the constructor (at least optionally) that way you can disconnect it and pass in a mock/stub object.
您应该测试您的模型(调用您的映射器)。这样,您就会知道您的映射器是否有问题。
您是否尝试过在 Artists 模型中设置映射器方法,例如
public function setMapper(Ly_Model_ArtistMapper $mapper)
{
...
}
You should test your models (which call your mapper). That way, you will know if something is wrong with your mappers.
Have you tried in your Artists model setting the mapper method like
public function setMapper(Ly_Model_ArtistMapper $mapper)
{
...
}
单元测试旨在测试少量工作,即方法。该方法所依赖的所有内容都应该被模拟/存根(成功/失败),因为这将在另一个单元测试的其他地方进行测试。
Unit tests are meant to test a small amount of work, i.e. a method. Everything that the method depends on should be mocked/stubbed (success/failure) out as that will be tested else where in another unit test.