2009-08-07 6 views
5

J'écris une nouvelle application avec CakePHP (just-released 1.2.4), en utilisant SimpleTest 1.0.1. J'ai lu les sections pertinentes du Cookbook, recherché sur le Bakery, et lu les publications de Mark Story sur les tests de contrôleur (les hard way et with mocks). Malheureusement, rien de tout cela ne parle de tests en conditions réelles de contrôleurs non triviaux. Beaucoup d'applications mettent des zones du site derrière un login, pourtant je ne peux pas comprendre comment tester le scénario simple de:Test en conditions réelles des contrôleurs CakePHP?

  • l'accès d'invité aux redirections de page protégées?
  • les informations d'identification valides définissent les variables de session attendues?
  • Les informations d'identification non valides réaffiche la page de connexion avec un message d'erreur?

Le contrôleur et le test ci-dessous ne fonctionnent pas comme je le pensais. Les deux affirmations échouent et je aussi obtenir une erreur de PHP:

ECHEC [NULL] ne doit pas être nulle à [.../app/tests/cas/contrôleurs/ligne users_controller.test.php 79] ... /app/tests/cases/controllers/users_controller.test.php -> UsersControllerTest -> tESTLOGIN

ECHEC attente Equal échoue [NULL] ne correspond pas [entier: 1] à [.../app/tests ligne /cases/controllers/users_controller.test.php 80] .../app/tests/cas/contrôleurs/users_controller.test.php -> UsersControllerTest -> tESTLOGIN

erreur Erreur PHP inattendue [Indéfini: action] gravité [E_NOTICE] dans [.../cake/libs/controller/composants/auth.php ligne 266] .../app/tests/cases/controllers/users_controller.test .php -> UsersControllerTest -> tESTLOGIN

Voici le contrôleur (cuit au four, plus la méthode de test "à la dure" Mark Story):

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

Voici le test:

/* 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); 
    } 
} 

Répondre

4

le test vous n'avez pas vraiment testé votre UsersContoller, vous testez vraiment le Au le composant. Si vous voulez faire cela, vous devez vous assurer que vous avez configuré votre TestUsersController de la même manière que dans votre application. Dans le cas de votre TESTLOGIN vous devez définir l'action et l'URL du contrôleur:

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

Sinon, je suggère de prendre un autre regard sur Mark's mock objects post et l'utilisation de ces méthodes pour écrire des tests pour le code du contrôleur et se moquant du composant Auth.

Questions connexes