2009-08-07 3 views
5

Sto scrivendo una nuova applicazione con CakePHP (appena rilasciato 1.2.4), usando SimpleTest 1.0.1. Ho letto le sezioni pertinenti di Cookbook, cercato su Bakery e letto i post di Mark Story sui test del controller (hard way e with mocks).Test sul mondo reale dei controller CakePHP?

Sfortunatamente, nessuno di questi parla di test sul mondo reale di controller non banali. Un sacco di app mettono le aree del sito dietro un login, ma non riesco a capire come testare lo scenario semplice di:

  • accesso guest ai reindirizzamenti delle pagine protette?
  • Le credenziali valide impostano le variabili di sessione previste?
  • credenziali non valide visualizza nuovamente la pagina di accesso con messaggio di errore?

Il controller e il test di seguito non funzionano come pensavo. Entrambe le affermazioni non riescono e ho anche ottenere un errore di PHP:

FAILED [NULL] non dovrebbe essere nulla a [.../app/test/casi/controller/linea users_controller.test.php 79] ... /app/tests/cases/controllers/users_controller.test.php -> UsersControllerTest -> TESTLOGIN

FAILED Pari aspettativa non riesce come [NULL] non corrisponde [Integer: 1] a [.../app/test linea /cases/controllers/users_controller.test.php 80] .../app/test/casi/controller/users_controller.test.php -> UsersControllerTest -> TESTLOGIN

ERRORE Errore PHP inatteso [indice indefinito: azione] severità [E_NOTICE] in [.../cake/libs/controller/components/auth.php line 266] .../app/tests/cases/controller/users_controller.test .php -> UsersControllerTest -> TESTLOGIN

Ecco il controller (al forno più metodo di prova di Mark Story "maniere forti"):

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

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

risposta

4

il test non hai davvero testato il tuo UsersContoller, stai davvero testando l'Au thComponent. Se vuoi farlo devi assicurarti di configurare TestUsersController nello stesso modo in cui si troverebbe nella tua app. Nel caso del vostro TESTLOGIN è necessario impostare l'azione e l'URL del controller:

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

In alternativa, vorrei suggerire di prendere un altro sguardo a Mark's mock objects post e l'utilizzo di tali metodi per scrivere test per il codice di controllo e beffardo il componente di autenticazione.