I want to know how to test the models in zend framework, but it give me a error when I run the test, the code is the following:
this is the model I want to test:
<?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)
);
}
}
it extends a base class, which is :
<?
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];
}
}
my test code is :
<?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'));
}
}
when I run the test,it give me error:
1) Model_User2Test::testCanFind
Undefined variable: _table
application\models\User2.php:57
tests\application\models\User2Test.php:27
why the _table is not defined? actually it is defined when I create the object? how could I fix it?
You declare _$table
as protected:
protected $_table = 'user';
So you can't access it as you are doing through an instantion of the class. Only a class that inherits can do that. You need to declare it public, or use a getter/setter style access.
Edit:
static function load($id) {
return self::_selectAndBind(
get_class(),
self::getDefaultAdapter()
->select()
// $this->_table not $table
->from($_table)
->where('id = ?', array($id)),
true);
}
In your class, you're using $_table and not $this->_table. This is the same in another location. Check over to make sure you're properly accessing class variables.
In your static method Application_Model_User::find()
, you have this line in your query:
->from($_table)
But in this context, $_table
is a local variable that never gets set. Sounds like you want to access $this->_table
instead.
[ As a side note: since you have defined find()
as a static method, you can run into issues when trying to reference $this
during a static call. Of course, in your test, you do seem to call the find()
on an instance, so you should be fine in this respect. Do you really need find()
to be a static method?]
精彩评论