3

我想在我的 UsersController.php 中测试 login() 操作

<?php
class UsersController extends AppController {
    public $helpers = array('Html', 'Form');
    public $components = array('RequestHandler');

    public function beforeFilter() {
        parent::beforeFilter();
        $this->Auth->allow('logout', 'login');
        // $this->Auth->allow('logout');
        $this->Security->csrfExpires = '+1 hour';
    }

    public function login() {
        if($this->request->is('post')) {
            if ($this->Auth->login()) {
                return $this->redirect($this->Auth->redirect());
            } else {
                $this->Session->setFlash(__('Invalid username or password, try again'),'info');
            }
        }
    }

AppController.php

<?php
App::uses('Controller', 'Controller');

class AppController extends Controller {

    public $components  = array(
        'Session',
        'Security',
        'Auth' => array(
            'loginRedirect' => array('controller' => 'dashboards', 'action' => 'index'),
            'logoutRedirect' => array('controller' => 'dashboards', 'action' => 'welcome'),
            'authorize' => array('Controller')
        )
    );

    public function isAuthorized($user) {
        //Admin can access every action
        if (isset($user['role']) && $user['role'] === 'admin') {
            return true;
        }

        //Default deny
        $this->Session->setFlash('You are not allowed to access the requested page');
        return false;
    }

}

UsersControllerTest.php

<?php

class UsersControllerTest extends ControllerTestCase {
    public $autoRender = false;
    public $fixtures = array('app.user','app.account');

    public function setUp() {
        parent::setUp();
        $this->User = ClassRegistry::init('User');
    }

...snip...
    public function testLogin() {

        $this->Users = $this->generate('Users', array(
            'components' => array(
                //'Session',
                'Security' => array('_validatePost'),
            )
        ));
        $this->Users->Security->expects($this->any())
             ->method('_validatePost')
             ->will($this->returnValue(true));

        $user = array();
        $user['User']['username'] = 'admin';
        //$user['User']['password'] = Security::hash('test', null, true);
        $user['User']['password'] = 'test';

        $result = $this->testAction('/users/login',
            array('data' => $user, 'method' => 'post', 'return' => 'contents')
        );

        debug( $this->contents); 
        //OUTPUTS: I get "Invalid username or password, try again"
        //EXPECTED: A successful login message since I provided the correct credentials

    }

那么,当什么都不返回时,我将如何测试我的 login() 方法$this->testAction('/users/login', array('data' => $user, 'method' => 'post', 'return' => 'contents'));

输出:我收到“无效的用户名或密码,请重试”

预期:由于我提供了正确的凭据,因此出现了成功的登录消息

任何答复将不胜感激。谢谢!

4

2 回答 2

4

感谢@jeremyharris,我能够测试我的 login()

用户控制器测试.php

public function testLogin() {
    $this->Users = $this->generate('Users', array(
        'components' => array(
            'Security' => array('_validatePost'),
        )
    ));

    $data = array();
    $data['User']['username'] = 'admin';
    $data['User']['password'] = 'test';

    $this->Users->Auth->logout();
    $this->testAction('/users/login',
        array('data' => $data, 'method' => 'post', 'return' => 'contents')
    );

    $result = $this->testAction('/',
        array('method' => 'get', 'return' => 'contents')
    );

    // debug($result); 
    $this->assertContains('You are logged in as: <span class="label">admin</span>',$result);
}

public function testLoginInvalid() {
    $this->Users = $this->generate('Users', array(
        'components' => array(
            'Security' => array('_validatePost'),
        )
    ));

    $data = array();
    $data['User']['username'] = 'admin';
    $data['User']['password'] = 'BLAH!';

    $this->Users->Auth->logout();
    $this->testAction('/users/login',
        array('data' => $data, 'method' => 'post', 'return' => 'contents')
    );

    $result = $this->testAction('/users/login',
        array('method' => 'get', 'return' => 'contents')
    );

    // debug($result); 
    $this->assertNotContains('You are logged in as',$result);
    $this->assertContains('id="UserLoginForm" method="post"',$result);
}

UserFixture.php,我使用了 init() 方法——正如@jeremyharris 关于散列密码所说的那样。

<?php
App::uses('AuthComponent', 'Controller/Component');

class UserFixture extends CakeTestFixture {
    /* Optional. Set this property to load fixtures to a different test datasource */
    public $useDbConfig = 'test';

    public $fields = array(
        'id' => array('type' => 'integer', 'key' => 'primary'),
        'account_id' => array('type' => 'integer'),
        'username' => array('type' => 'string', 'length' => 255, 'null' => false),
        'email' => array('type' => 'string', 'length' => 255, 'null' => false),
        'password' => array('type' => 'string', 'length' => 255, 'null' => false),
        'password_token' => array('type' => 'string', 'length' => 255, 'null' => false),
        'password_token_expiry' => array('type' => 'string', 'length' => 255, 'null' => false),
        'role' => array('type' => 'string', 'length' => 25, 'null' => false),
        'created' => 'datetime',
        'modified' => 'datetime'
    );

/*    public $records = array(
        array('id'=>1, 'account_id' => 1, 'username' => 'admin', 'email' => 'admin@test.com', 'password' => 'f57f702f8d557ae5318fa49455cbe9838c1d1712', 'role' => 'admin', 'password_token'=>'', 'password_token_expiry'=>'','created' => '2012-03-18 10:39:23', 'modified' => '2012-03-18 10:41:31'),
        array('id'=>2, 'account_id' => 1, 'username' => 'user', 'email' => 'user@test.com', 'password' => 'f57f702f8d557ae5318fa49455cbe9838c1d1712', 'role' => 'user', 'password_token'=>'', 'password_token_expiry'=>'', 'created' => '2012-03-18 10:39:23', 'modified' => '2012-03-18 10:41:31')
    );
*/
     public function init() {
        $this->records = array(
            array('id'=>1, 'account_id' => 1, 'username' => 'admin', 'email' => 'admin@test.com', 'password' => AuthComponent::password('test'), 'role' => 'admin', 'password_token'=>'', 'password_token_expiry'=>'','created' => '2012-03-18 10:39:23', 'modified' => '2012-03-18 10:41:31'),
            array('id'=>2, 'account_id' => 1, 'username' => 'user', 'email' => 'user@test.com', 'password' => AuthComponent::password('test'), 'role' => 'user', 'password_token'=>'', 'password_token_expiry'=>'','created' => '2012-03-18 10:39:23', 'modified' => '2012-03-18 10:41:31'),
        );
        parent::init();
    }
}

第一个 testAction() 是一个 POST,然后第二个得到“下一页”——从那里我做断言。

于 2012-06-19T00:41:56.470 回答
0

问题是您正在模拟整个 Session 组件。这意味着所有会话方法都将返回 null。从中删除“会话”键$this->generate(),您应该会很好。

于 2012-06-18T15:22:55.023 回答