2013-04-01 86 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); 
    } 
}