我正在为我的一个控制器编写CakePHP单元测试。 Controller对AuthComponent::user()
方法进行了多次调用,以读取当前登录用户的数据。有3种用法:
AuthComponent::user()
(没有参数,取整个数组)AuthComponent::user('id')
(获取用户ID)AuthComponent::user('name')
(提取用户名)我在测试中尝试了两种模拟AuthComponent的方法:
// Mock the Controller and the Components
$this->controller = $this->generate('Accounts', array(
'components' => array(
'Session', 'Auth' => array('user'), 'Acl'
)
));
// Method 1, write the entire user array
$this->controller->Auth->staticExpects($this->any())->method('user')
->will($this->returnValue(array(
'id' => 2,
'username' => 'admin',
'group_id' => 1
)));
// Method 2, specifically mock the AuthComponent::user('id') method
$this->controller->Auth->staticExpects($this->any())->method('user')
->with('id')
->will($this->returnValue(2));
但这些方法对我不起作用。方法1似乎根本不做任何事情,我的控制器中使用当前登录用户的id的保存操作返回null,因此未正确设置/获取该值。
方法2似乎有效,但是过于宽泛,它也会尝试将自己绑定到AuthComponent::user()
调用(没有params的调用),并且失败并显示错误:
方法名称的期望失败等于何时 调用零次或多次参数0进行调用 AuthComponent :: user(null)与期望值不匹配。失败 断言null匹配预期的'id'。
如何为AuthComponent获取正确的模拟,以便可以获得所有字段/变量?
答案 0 :(得分:2)
我就是这样做的。请注意,在此代码中,我使用“Employee”作为我的用户模型,但它应该很容易更改。
我有一个AppControllerTest.php超类,它返回'user'方法的回调。回调处理带有和没有参数的情况。 _generateMockWithAuthUserId
就是您所追求的 - 但请全部阅读。还有一些值得注意的事情,比如testPlaceholder。这是我的全班:
<?php
App::uses('Employee', 'Model');
/**
* EmployeeNotesController Test Case
* Holds common Fixture ID's and mocks for controllers
*/
class AppControllerTest extends ControllerTestCase {
public $authUserId;
public $authUser;
/**
* setUp method
*
* @return void
*/
public function setUp() {
parent::setUp();
$this->Employee = ClassRegistry::init('Employee');
}
/**
* tearDown method
*
* @return void
*/
public function tearDown() {
unset($this->Employee);
parent::tearDown();
}
public function testPlaceholder() {
// This just here so we don't get "Failed - no tests found in class AppControllerTest"
$this->assertTrue(true);
}
protected function _generateMockWithAuthUserId($contollerName, $employeeId) {
$this->authUserId = $employeeId;
$this->authUser = $this->Employee->findById($this->authUserId);
$this->controller = $this->generate($contollerName, array(
'methods' => array(
'_tryRememberMeLogin',
'_checkSignUpProgress'
),
'components' => array(
'Auth' => array(
'user',
'loggedIn',
),
'Security' => array(
'_validateCsrf',
),
'Session',
)
));
$this->controller->Auth
->expects($this->any())
->method('loggedIn')
->will($this->returnValue(true));
$this->controller->Auth
->staticExpects($this->any())
->method('user')
->will($this->returnCallback(array($this, 'authUserCallback')));
}
public function authUserCallback($param) {
if (empty($param)) {
return $this->authUser['Employee'];
} else {
return $this->authUser['Employee'][$param];
}
}
}
然后,我的控制器测试用例继承自该类:
require_once dirname(__FILE__) . DS . 'AppControllerTest.php';
class EmployeeNotesControllerTestCase extends AppControllerTest {
// Tests go here
当你想在测试中模拟auth组件时,你可以调用
$this->_generateMockWithAuthUserId('EmployeeNotes', $authUserId);
其中'EmployeeNotes'是控制器的名称,$ authUserId是测试数据库中用户的ID。