2010-07-28 8 views
9

J'ai une application qui se trouve derrière un login et utilise zend_acl et zend_auth.Test d'unité PHP avec Zend Auth et Zend ACL

Lors de la pré-expédition, j'ai un plugin ACL qui crée toutes les règles pour la liste de contrôle d'accès. J'ai aussi un plugin Auth qui vérifie si vous êtes connecté ou pas et si c'est le cas si vous avez accès à la ressource demandée en fonction de la liste de contrôle d'accès.

Comme l'application est entièrement derrière une connexion l'ACL est créé uniquement si vous êtes connecté.

Les tests unitaires cela semble impossible, ou un peu plus probable que je me manque quelque chose évidente.

Dans ma méthode de configuration de test unitaire, je simule une connexion réussie qui renvoie une instance de zend_auth. Les tests qui réussissent indiquent que cette connexion a réussi.

Cependant, si j'essaie ensuite de tester l'envoi vers un autre emplacement, ou si l'utilisateur connecté a accès à une ressource donnée, il est toujours rejeté par le plugin car il n'est toujours pas connecté. Je ne suis pas sûr pourquoi c'est, quelqu'un peut-il conseiller?

Par exemple, cela passe:

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

Cela échoue car il est rejeté par le plug-in:

public function testUserAccess() 
{ 

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

} 

Ce, j'ai trouvé semble encore être rediriger vers la page de connexion que les plug-ins ne sait pas que l'utilisateur est connecté.

Toute aide très appréciée.

Répondre

3

Le problème que vous décrivez se produit beaucoup avec l'utilisation de variables globales et la variable globale POO (le modèle Singleton).

Il y a un article par l'auteur de PHPUnit qui décrit comment vous pouvez éviter cela en utilisant l'injection de dépendance et quelles autres possibilités que vous avez et puisqu'il est très descriptif, je suggère que vous le lire :) http://sebastian-bergmann.de/archives/882-Testing-Code-That-Uses-Singletons.html

Comme une alternative laide (si vous avez besoin d'un résultat rapide) vous pouvez créer un bout de Zend_Auth (décrire dans le lien) et utiliser l'API de réflexion PHP 5.3 pour définir la variable d'instance Zend_Auth sur votre stub.

Espoir qui aide (comme la question a vécu une autre sans 4h réponse)

+0

Oui- merci qui semble être le problème. –

2

Voici une autre façon de créer un talon pour remplacer votre plugin ACL (ou tout autre plug-in) au cours des essais. Mettez-le dans votre ControllerTestCase et appelez-le dans le set-up de test.

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

De cette façon, votre méthode de preDispatch de souche est appelée à la place, qui contournera vos chèques de contrôle d'accès réel.