我正在测试一个控制器方法,该方法使用AppModel方法获取登录用户的帐户。问题是,我无法有效地模拟提供account_id的AppModel方法,而是在调试此值时获取null。请让我知道我错过了什么,或者我是否以错误的方式解决这个问题。
AppModel.php包括:
/**
* _getUser
*
* @param string $key from AuthComponent::user
* @return string value from AuthComponent::user
*/
public function _getUser($key = null) {
return AuthComponent::user($key);
}
AccountsController.php包括:
App::uses('AppController', 'Controller');
class AccountsController extends AppController {
public $name = 'Accounts';
/**
* memberLetters -
* Generate a letter to each member
*
**/
function memberLetters() {
$account_id = $this->Account->_getUser('account_id');
debug($account_id); // !!! returns null; expecting '1' !!!
}
}
用户模型(User.php)包括:
App::uses('AuthComponent', 'Controller/Component');
class User extends AppModel {
public $name = 'User';
public $actsAs = array('Acl' => array('type' => 'requester'));
public $validate = array(
'email' => array(
'email' => array(
'rule' => array('email'),
'message' => 'Email address required'),
'isUnique' => array(
'rule' => array('isUnique'),
'message' => 'This email address is already associated with an account.')
),
'password' => array(
'notempty' => array(
'rule' => array('notempty'),
'message' => 'Password required',
),
),
'account_id' => array(
'numeric' => array(
'rule' => array('numeric'),
),
),
);
public $belongsTo = array('Account');
}
测试代码:AccountsControllerTest.php包括:
App::uses('AccountsController', 'Controller');
class AccountsControllerTest extends ControllerTestCase {
/**
* Fixtures
*
* @var array
*/
public $fixtures = array(
'app.account',
'app.user',
);
/**
* testMemberLetters method
*
* @return void
*/
public function testMemberLetters() {
$model = $this->getMockForModel('Account', array('_getUser'), array());
$model
->expects($this->exactly(1))
->method('_getUser', array('account_id'))
->will($this->returnValue(1));
$result = $this->testAction(
'accounts/memberLetters',
array(
'method' => 'get',
'return' => 'vars',
)
);
}
答案 0 :(得分:0)
我通过将Accounts :: get_User()调用从AccountsController代码重构到Account模型代码来解决这个问题。这使它成为可测试的。感谢TimKoschützkihttp://debuggable.com/posts/implementing-different-types-for-cakes-modelfind-method:485030de-4778-456e-8400-44d84834cda3我找到了以下方式来覆盖模型 - >找到:
Accounts.php包含
function find($type = string, $queryData = array()) {
switch ($type) {
case 'mine':
if (!in_array('conditions', $queryData)) {
$queryData['conditions'] =
array('id' => $this->_getUser('account_id'));
} else {
$queryData['conditions'] .=
array('id' => $this->_getUser('account_id'));
}
return parent::find('first', $queryData);
default:
return parent::find($type, $queryData);
}
}
所以现在我的AccountsController方法可以简单地调用
$data = $this->Account->find('mine');
在我的AccountsControllerTest中我写了
public function testMemberLetters() {
$this->controller = $this->generate('Accounts', array(
'models' => array(
'Account' => array('_getUser')
)
));
$this->controller->Account->expects($this->exactly(1))
->method('_getUser')
->with('account_id')
->will($this->returnValue(1));
$result = $this->testAction(
'accounts/memberLetters',
array(
'method' => 'get',
'return' => 'vars',
)
);
}