Zend Framework:我应该如何在Zend_Db中对我的Mapper进行单元测试?

时间:2010-02-13 10:53:48

标签: unit-testing zend-framework zend-db

我如何在Zend_Db中测试我的映射器? 我的每个模型都有3个类:

  • 模特
  • The Mapper
  • The 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);
    }
}

我正在使用马修的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

似乎没有读取Mapper。谁能告诉我如何进行这种测试?我是UnitTesting的新手,我刚开始学习它。

这是我的艺术家模特

<?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);
    }
}

这是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;
    }
}

Db_Table看起来像这样:

<?php
class Ly_Model_DbTable_Artist extends Zend_Db_Table_Abstract
{
    protected $_name = 'artist';
}

3 个答案:

答案 0 :(得分:4)

更改映射器以使用控制反转模式(将DB表对象插入构造函数(至少可选),以便断开连接并传入模拟/存根对象。

答案 1 :(得分:1)

您应该测试您的模型(调用您的映射器)。这样,你就会知道你的地图制作者是否有问题。

您是否尝试过在Artists模型中设置映射器方法,如

public function setMapper(Ly_Model_ArtistMapper $ mapper) { ... }

答案 2 :(得分:0)

单元测试旨在测试少量工作,即一种方法。该方法依赖的所有内容都应该被模拟/存根(成功/失败),因为在另一个单元测试中将测试其他地方。