2013-04-01 13 views
5

Ho pensato di dover chiedere qui qualche aiuto per il mio problema. Ho passato la serata intera con questo. Ho un metodo di accesso in UsersController come questo:CakePHP 2.3 - Unit test Utente Login

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'); 
      } 
     } 
    } 

ho cercato di testare questo con PHPUnit, in modo da poter essere sicuri che solo gli utenti validi possono accedere → dopo un login riuscito saranno reindirizzati ad una specifica pagina. Ecco il mio metodo testLogin in UsersControllerTest classe:

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'); 
    } 

sto ancora imparando le basi di unit testing con CakePHP. Ottengo questo errore:

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

Non ho idea di cosa provoca questo ... Cosa c'è di sbagliato con il mio metodo di prova e come dovrebbe essere scritto?

Grazie!

+1

'$ questo-> intestazioni' non ha una chiave' Posizione'. Del resto ... da dove vengono le intestazioni "$ this-> headers"? –

+0

Forse stai cercando l'intestazione 'response'? [CakeResponse - Setting headers] (http://book.cakephp.org/2.0/en/controllers/request-response.html#setting-headers) – thaJeztah

risposta

2

ho ottenuto questo lavoro con il seguente codice:

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

Posso chiederti come si presenta il tuo Fixture per l'utente? Solo un normale Fixture o altro extra per ottenere la password hash? –

0

Io uso questo testcase per ignorare la chiamata torta Auth e Session e verificare se l'accesso è riuscito.

Questo è più di una soluzione generica che utilizzo nei miei test., Per ottenere i valori inseriti nella sessione dopo che l'utente ha effettuato l'accesso e anche per verificare se l'accesso ha esito positivo.

<?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); 
    } 
}