【问题标题】:Is it possible to mock a variable value for a method for CakePHP tests (PHP Unit)?是否可以模拟 CakePHP 测试(PHP 单元)的方法的变量值?
【发布时间】:2013-07-28 04:44:10
【问题描述】:

我正在测试我的 API,并且有一个用于 OAuth 的登录方法,我似乎无法正确测试它,因为它在 POST 时不会读取变量的 $_GET 值。

登录方式。基本上 $OAuthParams 在使用 POST 时不会被设置,因为 getAuthorizeParams() 使用 $_GET。 所以我想填充/模拟 $_GET 或 $OAuthParams。

public function login () {
    $OAuthParams = $this->OAuth->getAuthorizeParams();
    if ($this->request->is('post')) {
        $this->validateRequest();
        $loginData = array('User' => array(
                'username' => $this->request->data['User']['username'],
                'passwd' => $this->request->data['User']['passwd']
            ));
        //Attempted login
        if ($this->Auth->login($loginData['User'])) {
            unset($loginData);
            $userData = $this->User->find('first',array(
                'conditions' => array(
                    'User.username' => $this->request->data['User']['username']
                ),
                'fields' => array('username','name','id','banned','active','role','private'),
                'recursive' => -1
            ));

            $this->Session->write('Auth.User',$userData['User']); //Update the session

            //Write this to session so we can log them out after authenticating
            $this->Session->write('OAuth.logout', true);

            //Write the auth params to the session for later
            $this->Session->write('OAuth.params', $OAuthParams);

            //Off we go
            return $this->redirect(array('action' => 'authorize'));
        } else {
            $this->Session->setFlash(__('Username or password is incorrect'), 'default', array(), 'auth');
        }
    }
    $appName = $this->applicationDetails['name'];
    $this->set(compact('OAuthParams','appName'));
}

当前的测试方法。

/**
 * testAccessToken method
 * 1. Get the authorization code (/oauth/authorize?response_type=code&client_id=CLIENT_ID&client_secret=CLIENT_SECRET)
 * 2. Retrieve the token (/oauth/token?grant_type=authorization_code&code=CODE_RETURNED&client_id=CLIENT_ID&client_secret=CLIENT_SECRET)
 * 3. Parse the token from the returned data
 * @return void
*/
public function testAccessToken(){
    //@link http://stackoverflow.com/questions/8183396/dealing-with-security-component-in-a-cakephp-2-test-case
    $this->OAuth = $this->generate('OAuth', array(
        'components' => array(
            'Security' => array('_validatePost'),
        )
    ));
    $this->OAuth->Security->expects($this->any())
        ->method('_validatePost')
        ->will($this->returnValue(true));

    $get_data = array(
        'response_type' => 'code',
        'client_id' => getenv('THREE_SCALE_APP_ID'),
        'client_secret' => getenv('THREE_SCALE_APP_KEY'),
    );
    $post_data = array(
        'User' => array(
            'username' => 'test_user_1',
            'passwd' => 'tester'
        )
    );

    $resultPost = $this->testAction(
        '/oauth/login', 
        array(
            'method' => 'post',
            'data' => $post_data
        )
    );
    debug($resultPost);

    $data_for_code = array(
        'accept' => 'Yep',
        'Authorize' => array(
            'client_id' => getenv('THREE_SCALE_APP_ID'),
            'client_secret' => getenv('THREE_SCALE_APP_KEY'),
            'response_type' => 'code',
            'state' => '',
            'scope' => ''
        )
    );
    $code = $this->testAction(
        '/oauth/authorize', 
        array(
            'data' => $data_for_code, 
            'method' => 'post'
        )
    );
    debug($code);
    /*$data_for_token = array(
        'grant_type' => 'authorization_code',
        'code' => $code,
        'client_id' => getenv('THREE_SCALE_APP_ID'),
        'client_secret' => getenv('THREE_SCALE_APP_KEY')
    );
    $token = $this->testAction(
        '/oauth/token', 
        array(
            'data' => $data_for_token, 
            'method' => 'post'
        )
    );*/
    //debug($token);
}

尝试了以下方法,但没有成功。

$this->OAuth = $this->generate(
    'OAuth',
    array(
        'components' => array(
            'Security' => array( '_validatePost' ),
            'Auth' => array('loggedIn','user')
        ),
        'methods' => array(
            'getAuthorizeParams'
        )
    )
);
$data = array(
    'response_type' => 'code',
    'client_id' => getenv('THREE_SCALE_APP_ID'),
    'client_secret' => getenv('THREE_SCALE_APP_KEY')
);
$this->OAuth->expects($this->any())
    ->method('getAuthorizeParams')
    ->will($this->returnValue($data));

$loginData = array(
    'User' => array(
        'client_id' => getenv('THREE_SCALE_APP_ID'),
        'client_secret' => getenv('THREE_SCALE_APP_KEY'),
        'response_type' => 'code',
        'state' => '',
        'scope' => '',
        'redirect_uri' => 'https://myurl.com/api/myCallbackMethod',
        'username' => 'test_user_1',
        'passwd' => 'tester'
    )
);

//test login action
$resultPost = $this->testAction(
    '/oauth/login?response_type=code&client_id=' . getenv('THREE_SCALE_APP_ID') . '&client_secret=' . getenv('THREE_SCALE_APP_KEY'), 
    array(
        'method' => 'post',
        'data' => $loginData
    )
);
debug($resultPost);

$data = array(
    'accept' => 'Yep',
    'Authorize' => array(
        'client_id' => getenv('THREE_SCALE_APP_ID'),
        'client_secret' => getenv('THREE_SCALE_APP_KEY'),
        'response_type' => 'code',
        'state' => '',
        'scope' => ''
    )
);

$result = $this->testAction(
        '/oauth/authorize', 
        array(
            'data' => $data, 
            'method' => 'post'
        )
    );
debug($result);

【问题讨论】:

  • 模拟getAuthorizeParams() 函数以返回您想要的值。
  • CakePHP 2 中还有一个错误,它不能在单元测试中正确使用安全组件。确保您使用的是 2.3.6 或更高版本。
  • 是的,我也是这么想的,但是我尝试模拟 getAuthorizeParams(),但我仍然收到 {"error":"invalid_client","error_description":"No client id provided" }。感谢您的安全提示,我已升级到 2.3.8 版。
  • 要模拟的 OAuth 中的函数是带有 'methods' 键的字符串数组,即:$this->generate('OAuth', array('methods' => array('getAuthorizeParams'), 'components' => array(...));

标签: php cakephp phpunit cakephp-2.0


【解决方案1】:

模拟 getAuthorizeParams() 函数以返回您想要的值。

您要模拟的 OAuth 中的函数是带有 'methods' 键的字符串数组,即:

$this->generate(
    'OAuth', 
    array(
        'methods' => array(
            'getAuthorizeParams'
        ),
        'components' => array(
            ...
        )
    )
);

然后在调用testAction() 方法之前:

$this->OAuth->expects($this->once())
    ->method('getAuthorizeParams')
    ->will($this->returnValue($YOUR_EXPECTED_VALUE));

【讨论】:

  • 仍然没有运气。 :(
  • 它到底做错了什么/什么是意外行为?任何错误信息?你确定这个函数会被你传递的数据调用吗?
  • 错误是{"error":"invalid_client","error_description":"No client id supplied"}。通过浏览器使用时,登录和授权工作正常。注意:这是供参考的 OAuth 代码。我必须对其进行一些定制才能使其与 Threescale 一起使用。基本上 Threescale 正在处理所有的密钥,当它们得到验证时,我只是将它们放在本地数据库中。可能比你需要知道的要多一点,但是 owell。再次感谢您的帮助。 github.com/robksawyer/cakephp-oauth-server/blob/master/…
猜你喜欢
  • 1970-01-01
  • 2010-11-21
  • 2015-10-21
  • 2013-12-26
  • 2017-03-20
  • 2021-02-28
  • 2014-04-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多