phpunit-testingphpunitzend-authzend-acl

PHP Unit Testing with Zend Auth and Zend ACL


I have an application that is behind a login and utilizes zend_acl and zend_auth.

During pre-dispatch I have an ACL plugin that creates all the rules out for the ACL. I also have an Auth plugin that checks if you're logged in or not and if so if you have access to the requested resource according to the ACL.

As the application is entirely behind a login the ACL is only created if you're logged in.

Unit testing this appears to be impossible, or rather more likely I'm missing something obvious.

In my unit test setup method I simulate a successful login that returns a zend_auth instance. Tests that do pass indicate that this login was successful.

However, if I then through tests attempt to dispatch to another location, or assess if the logged in user has access to a given resource it is always rejected by the plugin as they're still not logged in. I am not sure why this is, can anyone advise?

For example this passes:

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

This fails as it's rejected by the plugin:

 public function testUserAccess()
 {

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

 }

This, I have found still seems to be redirecting back to the login page as the plugins don't know the user is logged in.

Any help much appreciated.


Solution

  • The Problem you describe happens a lot with the usage of global variables and the OOP global variable (the Singleton Pattern).

    There is an article by the author of PHPUnit that describes how you can avoid that by using Dependency Injection and what other possibilities you've got and since it's very descriptive, I just suggest you to read it :) http://sebastian-bergmann.de/archives/882-Testing-Code-That-Uses-Singletons.html

    As an ugly alternative (if you need a quick result) you could create a stub of Zend_Auth (describe in the link) and use the PHP 5.3 reflection API to set the Zend_Auth instance variable to your stub.

    Hope that helps (as the question lived 4h without an other answer)