2010-07-28 8 views
9

Ho un'applicazione che si trova dietro un login e utilizza zend_acl e zend_auth.Test dell'unità PHP con Zend Auth e Zend ACL

Durante la pre-spedizione ho un plugin ACL che crea tutte le regole per l'ACL. Ho anche un plugin Auth che controlla se sei loggato o meno e in tal caso se hai accesso alla risorsa richiesta secondo l'ACL.

Poiché l'applicazione è del tutto una procedura di accesso ACL si crea solo se si è registrato in.

Unit testing questo sembra essere impossibile, o meglio, più probabilmente mi manca qualcosa di ovvio.

Nel metodo di installazione test della mia unità, simulo un accesso riuscito che restituisce un'istanza zend_auth. I test che superano indicano che questo login ha avuto successo.

Tuttavia, se attraverso i test provo a inviare in un'altra posizione o se l'utente che ha effettuato l'accesso ha accesso a una determinata risorsa, viene sempre rifiutato dal plug-in in quanto non è ancora connesso. certo perché questo è, qualcuno può consigliare?

Per esempio, questo passa:

public function testLoggedIn() 
{ 
    $this->assertTrue(Zend_Auth::getInstance()->hasIdentity()); 
} 

Questo fallisce come è respinta dal plugin:

public function testUserAccess() 
{ 

    $this->dispatch('/home'); 
      $this->assertResponseCode(200); 
      $this->assertQueryContentContains('#nav_side'); 
      $this->resetRequest() 
      ->resetResponse(); 

} 

questo, ho trovato sembra essere ancora il reindirizzamento di nuovo alla pagina di login come i plugin non so che l'utente ha effettuato il login.

Qualsiasi aiuto molto apprezzato.

risposta

3

Il problema che descrivi si verifica molto con l'utilizzo di variabili globali e la variabile globale OOP (il modello Singleton).

C'è un articolo dall'autore di PHPUnit che descrive come si può evitare che utilizzando Dependency Injection e quali altre possibilità che hai e dal momento che è molto descrittivo, ho solo suggerisco di leggere it :) http://sebastian-bergmann.de/archives/882-Testing-Code-That-Uses-Singletons.html

Come una brutta alternativa (se hai bisogno di un risultato rapido) potresti creare uno stub di Zend_Auth (descrivi nel link) e usare l'API di riflessione PHP 5.3 per impostare la variabile di istanza Zend_Auth sul tuo stub.

Speranza che aiuta (come la questione ha vissuto 4h senza altra risposta)

+0

Sì, grazie che sembra essere il problema. –

2

Ecco un altro modo di creare uno stub per sostituire il vostro plugin ACL (o alcun plugin) durante il test. Metti questo nel tuo ControllerTestCase e chiamalo nel set-up del test case.

public function doLogin() 
{ 
    // create a fake identity 
    $identity = new stdClass(); 
    $identity->Username = 'PHPUnit'; 
    Zend_Auth::getInstance()->getStorage()->write($identity); 

    // remove the autoloaded plugin 
    $front = Zend_Controller_Front::getInstance(); 
    $front->unregisterPlugin('My_Controller_Plugin_Acl'); 

    // create the stub for the Acl class 
    $mockaAcl = $this->getMock(
     'My_Controller_Plugin_Acl', 
     array('preDispatch'), 
     array(), 
     'My_Controller_Plugin_AclMock' 
    ); 

    // register the stub acl plugin in its place 
    $front->registerPlugin($mockAcl); 
} 

In questo modo viene chiamato il metodo preDispatch stub, che eviterà i controlli di controllo di accesso effettivi.