Php 如何测试内部使用AuthComponent::user的模型方法

Php 如何测试内部使用AuthComponent::user的模型方法,php,unit-testing,cakephp,mocking,cakephp-2.0,Php,Unit Testing,Cakephp,Mocking,Cakephp 2.0,我正在使用CakePHP2.4 我有一个叫做故事书的模型课 有一个名为createDraft的方法,其代码如下所示: public function createDraft($data) { $data['Storybook']['author'] = AuthComponent::user('id'); <?php App::uses('Storybook', 'Model'); class StorybookTestCase extends CakeTe

我正在使用CakePHP2.4

我有一个叫做故事书的模型课

有一个名为createDraft的方法,其代码如下所示:

    public function createDraft($data) {
        $data['Storybook']['author']    = AuthComponent::user('id');
<?php
App::uses('Storybook', 'Model');
class StorybookTestCase extends CakeTestCase {

/**
 * Fixtures
 *
 * @var array
 */
    public $fixtures = array(...
    );

/**
 * setUp method
 *
 * @return void
 */
    public function setUp() {
        parent::setUp();
        $this->Storybook    = ClassRegistry::init('Storybook');
...
...


/**
 * GIVEN we have only a title
 * WHEN we call createDraft
 * THEN we have a new draft
 *
 * @return void
 */
     public function testCreateDraftSuccessfully() {    
        // GIVEN only a title
        $data = array('Storybook' => array('title' => 'some title'));
        // WHEN we call the createDraft
        $actualResult = $this->Storybook->createDraft($data);
 ....
当我使用CakePHP测试编写测试脚本时,我在实例化AuthComponent中的用户数据时遇到了问题

我的测试脚本如下所示:

    public function createDraft($data) {
        $data['Storybook']['author']    = AuthComponent::user('id');
<?php
App::uses('Storybook', 'Model');
class StorybookTestCase extends CakeTestCase {

/**
 * Fixtures
 *
 * @var array
 */
    public $fixtures = array(...
    );

/**
 * setUp method
 *
 * @return void
 */
    public function setUp() {
        parent::setUp();
        $this->Storybook    = ClassRegistry::init('Storybook');
...
...


/**
 * GIVEN we have only a title
 * WHEN we call createDraft
 * THEN we have a new draft
 *
 * @return void
 */
     public function testCreateDraftSuccessfully() {    
        // GIVEN only a title
        $data = array('Storybook' => array('title' => 'some title'));
        // WHEN we call the createDraft
        $actualResult = $this->Storybook->createDraft($data);
 ....

我在谷歌搜索和询问#cakephp IRC频道后得出的步骤:

1) 确保您至少使用CakePHP 2.3

2) 在AppModel中创建以下受保护的函数:

protected function _getUser($key = null) {
    return AuthComponent::user($key);
}
//type this just below App::uses('Model', 'Model');
App::uses('AuthComponent', 'Controller/Component');
3) 确保在AppModel中实际使用了AuthComponent:

protected function _getUser($key = null) {
    return AuthComponent::user($key);
}
//type this just below App::uses('Model', 'Model');
App::uses('AuthComponent', 'Controller/Component');
4) 将故事书模型更改为使用_getUser而不是AuthComponent::user

    public function createDraft($data) {
        $data['Storybook']['author']    = $this->_getUser('id');
5) 为此,在试验方法中添加以下内容:

那将帮助你通过考试

更新

如果要模拟的方法可能会根据不同的参数返回不同的结果,则需要有另一个公共函数作为模拟方法的回调函数

步骤5的替代方法)如果希望在参数为'id'时始终返回23,在参数为'group_id'时始终返回1,请添加以下函数

public function getUserCallBack($field) {
        if ($field == 'id') {
            return 23;
        }
        if ($field == 'group_id') {
            return 1;
        }
    }
6) 将试验方法更改为:

public function testCreateDraftSuccessfully() {    

        // MOCK the _getUser method to always return 23 for _getUser('id') and 1 for _getUser('group_id')
        $this->Storybook = $this->getMockForModel('Storybook', array('_getUser'));
        $this->Storybook->expects($this->once())
        ->method('_getUser')
        ->with($this->logicalOr(
            $this->equalTo('id'),
            $this->equalTo('group_id')
        ))
        ->will($this->returnCallback(array($this, 'getUserCallBack')));

    // GIVEN only a title
    $data = array('Storybook' => array('title' => 'some title'));
例如


通过谷歌搜索和询问#cakephp IRC频道,我发现了以下步骤:

1) 确保您至少使用CakePHP 2.3

2) 在AppModel中创建以下受保护的函数:

protected function _getUser($key = null) {
    return AuthComponent::user($key);
}
//type this just below App::uses('Model', 'Model');
App::uses('AuthComponent', 'Controller/Component');
3) 确保在AppModel中实际使用了AuthComponent:

protected function _getUser($key = null) {
    return AuthComponent::user($key);
}
//type this just below App::uses('Model', 'Model');
App::uses('AuthComponent', 'Controller/Component');
4) 将故事书模型更改为使用_getUser而不是AuthComponent::user

    public function createDraft($data) {
        $data['Storybook']['author']    = $this->_getUser('id');
5) 为此,在试验方法中添加以下内容:

那将帮助你通过考试

更新

如果要模拟的方法可能会根据不同的参数返回不同的结果,则需要有另一个公共函数作为模拟方法的回调函数

步骤5的替代方法)如果希望在参数为'id'时始终返回23,在参数为'group_id'时始终返回1,请添加以下函数

public function getUserCallBack($field) {
        if ($field == 'id') {
            return 23;
        }
        if ($field == 'group_id') {
            return 1;
        }
    }
6) 将试验方法更改为:

public function testCreateDraftSuccessfully() {    

        // MOCK the _getUser method to always return 23 for _getUser('id') and 1 for _getUser('group_id')
        $this->Storybook = $this->getMockForModel('Storybook', array('_getUser'));
        $this->Storybook->expects($this->once())
        ->method('_getUser')
        ->with($this->logicalOr(
            $this->equalTo('id'),
            $this->equalTo('group_id')
        ))
        ->will($this->returnCallback(array($this, 'getUserCallBack')));

    // GIVEN only a title
    $data = array('Storybook' => array('title' => 'some title'));
例如