我想知道如何在zend框架中测试模型,但是当我运行测试时它会给我一个错误,代码如下:
这是我要测试的模型:
<?php
class Application_Model_User extends Custom_Model_Base {
protected $_table = 'user';
protected $_primary = array('id');
protected $_primary_ai = 'id';
protected $_data = array();
protected $_data_changed = array();
protected $_readonly = array('id');
static
protected $_columns = array(
'id',
'login',
'password_hash',
'name',
'surname',
'gender',
'street',
'postal_code',
'city',
'mobile',
'homephone',
'email',
'is_active');
public function __construct() {
parent::__construct();
}
static function create(array $data) {
return parent::_create(
$_table,
get_class(),
$data,
self::$_columns,
true
);
}
static function load($id) {
return self::_selectAndBind(
get_class(),
self::getDefaultAdapter()
->select()
->from($_table)
->where('id = ?', array($id)),
true);
}
static function find($name, $order=null, $limit=null, $offset=null) {
return self::_selectAndBind(
get_class(),
self::getDefaultAdapter()
->select()
->from($_table)
->where('name = ?', array($name))
->order($order)
->limit($limit, $offset)
);
}
}
它扩展了一个基类,即:
<?
abstract class Custom_Model_Base
{
/** @var Zend_Db_Adapter_Abstract */
static protected $_db_default = null;
/** @var Zend_Db_Adapter_Abstract */
protected $_db = null;
protected $_table = '';
protected $_primary = array();
/** $var string indicates which column from pk using auto increment function, set to null if none column is using auto incrementation */
protected $_primary_ai = null;
protected $_data = array();
protected $_data_changed = array();
protected $_readonly = array();
/**
* @param Zend_Db_Adapter_Abstract $adapter overrides global (static) adapter used for all models
*/
protected function __construct($adapter=null) {
if ($adapter !== null) {
if ($adapter instanceof Zend_Db_Adapter_Abstract)
{
$this->_db = $adapter;
return;
}
$this->_db = &self::$_db_default;
}
}
/**
* @param $default_adapter allows to set default adapter for whole model layer based on that class
*/
static public function init($default_adapter = null)
{
if (self::$_db_default === null)
{
if (!is_null($default_adapter))
{
if (!$default_adapter instanceof Zend_Db_Adapter_Abstract)
{
throw new Exception('Provided adapter does not extend Zend_Db_Adapter_Abstract');
}
self::$_db_default = $default_adapter;
}
else if (Zend_Registry::isRegistered('db'))
{
self::$_db_default = Zend_Registry::get('db');
}
else
{
throw new Exception('No default adapter provided for the model layer');
}
}
}
/**
* @return Zend_Db_Adapter_Abstract default database adapter
*/
static public function getDefaultAdapter()
{
return self::$_db_default;
}
/**
* Saves changed columns from the model object
* @return bool success - true / failure - false
*/
public function save()
{
$to_update = array();
foreach(array_keys($this->_data_changed) as $col)
{
$to_update[$col] = $this->_data[$col];
}
if (count($to_update))
{
// create where clause
$where = array();
foreach($this->_primary as $pk)
{
$where = array($pk.' = ?' => $this->_data[$pk]);
}
return ($this->_db->update($this->_table, $to_update, $where) != 0);
}
else
{
return true;
}
}
public function __set($n, $v)
{
if (!isset($this->_data[$n]))
{
throw new Exception('Column \''.$n.'\' doesn\'t exists');
}
else if (in_array($n, $this->_readonly))
{
throw new Exception('Column \''.$n.'\' is set as read-only');
}
if ($this->_data[$n] != $v)
{
$this->_data_changed[$n] = 1;
$this->_data[$n] = $v;
}
}
public function __get($v)
{
if (!isset($this->_data[$n]))
{
throw new Exception('Column \''.$n.'\' doesn\'t exists');
}
return $this->_data[$n];
}
}
我的测试代码是:
<?php
require_once(APPLICATION_PATH.'/models/CustomModelBase.php');
class Model_User2Test
extends PHPUnit_Framework_TestCase
{
protected $_model;
public function setUp() {
parent::setUp();
$this->_model = new Application_Model_User2();
//$foo = $this->getMock();
}
public function testCanDoTest() {
$this->assertInstanceOf('Application_Model_User2', $this->_model);
//$this->assertType('Application_Model_User2',new Application_Model_User2());
}
public function testCanFind() {
$this->assertTrue(true);
$this->_model->init();
$this->assertNotNull($this->_model->find('admin'));
}
}
当我运行测试时,它会给我错误:
1) Model_User2Test::testCanFind
Undefined variable: _table
application\models\User2.php:57
tests\application\models\User2Test.php:27
为什么没有定义_table?实际上它是在我创建对象时定义的?我怎么能解决它?
答案 0 :(得分:2)
您将_$table
声明为受保护的:
protected $_table = 'user';
因此,您无法通过课程的实例访问它。只有继承的类才能做到这一点。您需要将其声明为public,或使用getter / setter样式访问。
编辑:
static function load($id) {
return self::_selectAndBind(
get_class(),
self::getDefaultAdapter()
->select()
// $this->_table not $table
->from($_table)
->where('id = ?', array($id)),
true);
}
在您的课程中,您使用的是$ _table而不是$ this-&gt; _table。这在另一个位置是相同的。检查以确保您正确访问类变量。
答案 1 :(得分:1)
在静态方法Application_Model_User::find()
中,您的查询中包含以下行:
->from($_table)
但在这种情况下,$_table
是一个永远不会被设置的局部变量。听起来您想要访问$this->_table
。
[作为旁注:由于您已将find()
定义为静态方法,因此在静态调用期间尝试引用$this
时可能会遇到问题。当然,在您的测试中,您似乎确实在实例上调用find()
,因此您应该在这方面做得很好。你真的需要find()
作为静态方法吗?]