2009-08-07 7 views
5

Estoy escribiendo una nueva aplicación con CakePHP (recién lanzado 1.2.4), usando SimpleTest 1.0.1. He leído las secciones pertinentes del Cookbook, busqué en el Bakery, y leí las publicaciones de Mark Story en las pruebas del controlador (hard way y with mocks).prueba en el mundo real de los controladores CakePHP?

Lamentablemente, nada de esto se refiere a las pruebas en el mundo real de controladores no triviales. Un montón de aplicaciones ponen las áreas del sitio detrás de un inicio de sesión, sin embargo, no pueden encontrar la manera de probar el escenario simple: el acceso

  • invitado a las redirecciones de páginas protegidas?
  • credenciales válidas establece las variables de sesión esperadas?
  • credenciales no válidas vuelve a mostrar la página de inicio de sesión con el mensaje de error?

El controlador y la prueba a continuación no funcionan como pensé que lo harían. Ambas afirmaciones fallan y también me sale un error de PHP:

FALLA [NULL] no debe ser nula en [.../app/tests/casos/controladores/línea users_controller.test.php 79] ... /app/tests/cases/controllers/users_controller.test.php -> UsersControllerTest -> TESTLOGIN

fALLA Igualdad expectativa falla como [NULL] no coincide con [Entero: 1] a [.../app/pruebas línea de /cases/controllers/users_controller.test.php 80] .../app/tests/casos/controladores/users_controller.test.php -> UsersControllerTest -> TESTLOGIN

ERROR Error inesperado de PHP [Índice no definido: acción] gravedad [E_NOTICE] en [.../cake/libs/controller/components/auth.php línea 266] .../app/tests/cases/controllers/users_controller.test .php -> UsersControllerTest -> TESTLOGIN

Aquí es el controlador (al horno, más método de ensayo de Mark Story "malas"):

class UsersController extends AppController 
{ 
    var $name = 'Users'; 
    var $helpers = array('Html', 'Form'); 
    var $components = array('Auth'); 

    function login() 
    { 
    } 

    function logout() 
    { 
    $this->redirect($this->Auth->logout()); 
    } 

    function index() 
    { 
    $this->set('users', $this->paginate()); 
    } 

    function view($id = null) 
    { 
    if (!$id) 
    { 
     $this->Session->setFlash(__('Invalid User.', true)); 
     $this->redirect(array('action'=>'index')); 
    } 
    $this->set('user', $this->User->read(null, $id)); 
    } 

    function add() 
    { 
    if (!empty($this->data)) 
    { 
     $this->User->create(); 
     if ($this->User->save($this->data)) 
     { 
     $this->Session->setFlash(__('The User has been saved', true)); 
     $this->redirect(array('action'=>'index')); 
     } 
     else 
     { 
     $this->Session->setFlash(__('The User could not be saved. Please, try again.', true)); 
     } 
    } 
    } 

    function edit($id = null) 
    { 
    if (!$id && empty($this->data)) 
    { 
     $this->Session->setFlash(__('Invalid User', true)); 
     $this->redirect(array('action'=>'index')); 
    } 
    if (!empty($this->data)) 
    { 
     if ($this->User->save($this->data)) 
     { 
     $this->Session->setFlash(__('The User has been saved', true)); 
     $this->redirect(array('action'=>'index')); 
     } 
     else 
     { 
      $this->Session->setFlash(__('The User could not be saved. Please, try again.', true)); 
     } 
    } 
    if (empty($this->data)) 
    { 
     $this->data = $this->User->read(null, $id); 
    } 
    } 

    function delete($id = null) 
    { 
    if (!$id) 
    { 
     $this->Session->setFlash(__('Invalid id for User', true)); 
     $this->redirect(array('action'=>'index')); 
    } 
    if ($this->User->del($id)) 
    { 
     $this->Session->setFlash(__('User deleted', true)); 
     $this->redirect(array('action'=>'index')); 
    } 
    } 
} 

Aquí está la prueba:

/* SVN FILE: $Id$ */ 
/* UsersController Test cases generated on: 2009-08-05 17:08:03 : 1249507923*/ 
App::import('Controller', 'Users'); 

class TestUsers extends UsersController 
{ 
    var $autoRender = false; 
    var $redirectUrl; 
    var $redirectStatus; 
    var $renderedAction; 
    var $renderedLayout; 
    var $renderedFile; 
    var $stopped; 

    function redirect($url, $status = null, $exit = true) 
    { 
    $this->redirectUrl = $url; 
    $this->redirectStatus = $status; 
    } 

    function render($action = null, $layout = null, $file = null) 
    { 
    $this->renderedAction = $action; 
    $this->renderedLayout = (is_null($layout) ? $this->layout : $layout); 
    $this->renderedFile = $file; 
    } 

    function _stop($status = 0) 
    { 
    $this->stopped = $status; 
    } 
} 

class UsersControllerTest extends CakeTestCase 
{ 
    var $fixtures = array('user'); 
    var $Users = null; 

    function startTest() 
    { 
    $this->Users = new TestUsers(); 
    $this->Users->constructClasses(); 
    $this->Users->Component->initialize($this->Users); 
    } 

    function prepareForAction() 
    { 
    $this->Users->beforeFilter(); 
    $this->Users->Component->startup($this->Users); 
    } 

    function endTest() 
    { 
    $this->Users->Session->destroy(); 
    unset($this->Users); 
    ClassRegistry::flush(); 
    } 

    //----------------------------------------------------------------------- 

    function testUsersControllerInstance() 
    { 
    $this->assertTrue(is_a($this->Users, 'UsersController')); 
    } 

    function testLogin() 
    { 
    $this->Users->data = array(
     'User' => array(
     'username' => 'admin', 
     'password' => 'admin' 
    ) 
    ); 

    $this->prepareForAction(); 
    $this->Users->login(); 

    $this->assertNotNull($this->Users->redirectUrl); 
    $this->assertEqual($this->Users->Session->read('Auth.User.id'), 1); 
    } 
} 

Respuesta

4

la prueba no está realmente probando su UsersContoller, realmente está probando el Au thComponent. Si desea hacer esto, debe asegurarse de configurar su TestUsersController de la misma manera que lo haría en su aplicación. En el caso de que su TESTLOGIN es necesario configurar la acción del controlador y url:

function testLogin() 
{ 
$this->Users->data = array(
       'User' => array(
        'username' => 'admin', 
        'password' => 'admin' 
       ) 
      ); 

$this->Users->params['url']['url'] = '/users/login'; 
$this->Users->params['action'] = 'login'; 
$this->prepareForAction(); 
$this->Users->login(); 

$this->assertNotNull($this->Users->redirectUrl); 
$this->assertEqual($this->Users->Session->read('Auth.User.id'), 1); 
} 

Alternativamente, sugeriría tomar otro vistazo a Mark's mock objects post y el uso de esos métodos para escribir pruebas para el código del controlador y burlón el componente de autenticación.

Cuestiones relacionadas