CakePHP 2.3 - Модульное тестирование Вход пользователя

Я подумал, что должен попросить здесь помощи в моей проблеме. Я провел весь вечер с этим. У меня есть метод входа в UsersController следующим образом:

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)

Я понятия не имею, что вызывает это... Что не так с моим методом тестирования и как его следует написать?

Спасибо!


person user1428033    schedule 01.04.2013    source источник
comment
$this->headers нет ключа Location. Если уж на то пошло... откуда $this->headers?   -  person Colin M    schedule 01.04.2013
comment
Может быть, вы ищете заголовок «ответ»? CakeResponse — Настройка заголовков   -  person thaJeztah    schedule 02.04.2013


Ответы (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( "/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( '"/users/login" id="UserLoginForm"', $foo );

        //logout mocked user
        $this->Users->Auth->logout();
    }
person user1428033    schedule 03.04.2013
comment
могу я спросить, как выглядит ваш Fixture for the User? Просто обычный Fixture или что-то еще для получения хешированного пароля? - person Calamity Jane; 27.03.2014

Я использую этот тестовый пример, чтобы переопределить вызов торта 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' => 'abcd1234'));
    $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);
  }
}
person souparno majumder    schedule 24.08.2016
comment
Пожалуйста, удалите мой адрес электронной почты из этого ответа. - person Gurpreet Singh; 30.05.2019