2013-04-01 87 views
5

我想我在这里问一些帮助我的问题。我花了整整一晚上。我有这样的UsersController登录方法:CakePHP 2.3 - 单元测试用户登录

public function login() { 

     if ($this->request->is('post')) { 
      if ($this->Auth->login()) { 
       $this->redirect(array('controller' => 'reservations', 'action' => 'index')); 
      } else { 
       $this->Session->setFlash(__('Login error.'), 'flashError'); 
      } 
     } 
    } 

我试图用PHPUnit的来测试这一点,这样我就可以确保只有合法的用户登录成功,他们将被重定向到一个特定的后登录→页。这里是我的testLogin方法UsersControllerTest类:

function testLogin() { 

     $UsersController = $this->generate('Users', array(
       'components' => array(
        'Auth' => array('user') 
       ), 
      ) 
     ); 

     $UsersController->Auth->expects($this->any()) 
     ->method('user') 
     ->with('id') 
     ->will($this->returnValue(2)); 

     $data = array('User' => array(
       'student_number' => 1111111, 
       'password' => 'qwerty' 
      )); 

     //$UsersController->Auth->login($data['User']); 

     $this->testAction('/users/login', array('data' => $data, 'method' => 'get')); 
     $url = parse_url($this->headers['Location']); 
     $this->assertEquals($url['path'], '/reservations'); 
    } 

我仍然在学习与CakePHP的单元测试的基础知识。我得到这个错误:

PHPUNIT_FRAMEWORK_ERROR_NOTICE 
Undefined index: Location 
Test case: UsersControllerTest(testLogin) 

我不知道是什么原因导致这...这有什么错我的测试方法,它应该怎么写?

谢谢!

+1

'$ this-> headers'没有'Location'键。对于这个问题...... $ this-> headers来自哪里? –

+0

也许你正在寻找'响应'标题? [CakeResponse - 设置标题](http://book.cakephp.org/2.0/en/controllers/request-response.html#setting-headers) – thaJeztah

回答

2

我得到这个工作用下面的代码:

function testLogin() { 

     //mock user 
     $this->Users = $this->generate('Users', array(
       'components' => array(
        'Security' => array('_validatePost'), 
       ) 
      )); 

     //create user data array with valid info 
     $data = array(); 
     $data['User']['student_number'] = 1234567; 
     $data['User']['password'] = '[valid password here]'; 

     //test login action 
     $result = $this->testAction("https://stackoverflow.com/users/login", array(
       "method" => "post", 
       "return" => "contents", 
       "data" => $data 
      ) 
     ); 

     $foo[] = $this->view; 
     //debug($foo); 

     //test successful login 
     $this->assertNotNull($this->headers['Location']); 
     $this->assertContains('reservations', $this->headers['Location']); 
     $this->assertNotContains('"https://stackoverflow.com/users/login" id="UserLoginForm"', $foo); 

     //logout mocked user 
     $this->Users->Auth->logout(); 
    } 
+0

请问你的用户夹具是怎么样的?只是一个正常的夹具或任何额外的获取哈希密码? –

0

我用这个测试用例覆盖蛋糕Auth通话和Session,并检查是否登录成功。

这是我在测试中使用的更通用的解决方案,用于在用户登录后将值输入会话并检查登录是否成功。

<?php 
App::uses('UsersController', 'Controller'); 
App::uses('AuthComponent', 'Controller/Component'); 
App::uses('CakeRequest', 'Network'); 
App::uses('CakeResponse', 'Network'); 

$_SERVER['HTTP_USER_AGENT'] = ''; 

class stubSession { 
    public $data = array(); 

    public function write($key, $value){ 
    $this->data[$key] = $value; 
    } 

    public function read($key){ 
    if(array_key_exists($key, $this->data)){ 
     return $this->data[$key]; 
    } 
    } 

    public function renew() { 

    } 

    public function setFlash(){ 

    } 

    public function delete() { 

    } 

    public function check(){ 

    } 
} 

class stubRequest { 
    public $data = array(); 

    function __construct($data) { 
    $this->data = $data; 
    } 

    public function is() { 
    return true; 
    } 

    public function clientIp(){ 

    } 
} 

class stubAuthComponent extends AuthComponent{ 

    public static $_session; 

    public function __construct($args, $session){ 
    parent::__construct($args); 
    $this->Session = $session; 
    self::$_session = $session; 
    $this->request = new CakeRequest(); 
    $this->response = new CakeResponse(); 
    } 

    public function loggedIn() { 
    return self::$_session->read(self::$sessionKey) != array(); 
    } 

    public function logout(){ 

    } 

    public static function user($key) { 
    $user = self::$_session->read(self::$sessionKey); 
    return $user[$key]; 
    } 
} 

class UsersControllerTest extends UsersController { 

    function __construct($data){ 
    $this->User = ClassRegistry::init('User'); 
    $this->Session = new stubSession(); 
    $this->Auth = new stubAuthComponent(new ComponentCollection(), $this->Session); 
    $this->request = new stubRequest($data); 
    } 

    public function redirect(){ 

    } 
} 

class TestUsersController extends CakeTestCase { 

    public function testLogin(){ 
    $_POST = array('User' => array('email' => '[email protected]', 'username' => '[email protected]', 'password' => 'testuser123')); 
    $usersController = new UsersControllerTest($_POST); 
    $usersController->login(); 
    $login = $usersController->Auth->loggedIn(); 
    //debug($usersController->Session->data); //you can test the session key value in here 
    $this->assertEquals($login, true); 
    } 
}