2011-05-11 57 views
0

我想知道如何測試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

在某些情況下,我用你,而不是1'Application_Model_User''Application_Model_User2'看到。我認爲這只是一個錯字? –

+0

@大衛,是的,大衛,這是一個錯字 – 2011-05-11 11:30:36

回答

2

您聲明_$table爲保護:

protected $_table = 'user'; 

所以,當你通過類的instantion做你不能訪問它。只有繼承的類才能做到這一點。需要聲明公開,或使用的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); 
} 

在你的類,你使用$γ_表,而不是$這 - > _表。這在另一個地方是一樣的。檢查一下以確保你正確地訪問類變量。

+0

改變了保護$ _table公共$γ_表,但它仍然是與更多的信息更新了同樣的錯誤 – 2011-05-11 11:04:23

+0

。訪問類變量,當你需要使用'$這個 - > variable'。 –

+0

我改變了保護$ _table在兩個Application_Model_User和Custom_Model_Base類公共的,但它給了同樣的錯誤 – 2011-05-11 11:16:58

1

在您的靜態方法Application_Model_User::find(),你有你的查詢這一行:

->from($_table)

但在這種情況下,$_table是永遠不會設置局部變量。聽起來像是你要訪問$this->_table代替。 [請注意:由於您已將find()定義爲靜態方法,因此在靜態調用期間嘗試引用$this時可能遇到問題。當然,在您的測試,你似乎調用find()實例,所以你應該在這方面的罰款。你真的需要find()是一個靜態方法?]

+0

我只是測試其他人編寫的代碼,所以我無法在基類中更改find​​()的訪問說明符,它提供了__set和__get方法,那麼如何在不更改訪問說明符的情況下解決問題?我不知道該怎麼做 – 2011-05-11 11:25:32

+0

然後它看起來像一個失敗的測試。究竟是什麼單元測試。 ;-) –

+0

但應用程序運行沒有問題 – 2011-05-11 11:45:04