2010-07-28 43 views
9

我有一个登录后面的应用程序,它使用zend_acl和zend_auth。使用Zend Auth和Zend ACL进行PHP单元测试

在预调度期间,我有一个ACL插件,为ACL创建所有规则。我还有一个Auth插件,用于检查您是否登录,如果有,您是否可以根据ACL访问请求的资源。

由于应用程序完全是一个登录,如果你在。

单元测试记录,这似乎是不可能的,或者说更可能我失去了一些东西明显ACL只落后创建。

在我的单元测试设置方法中,我模拟了一个成功的登录,它返回一个zend_auth实例。通过测试表明此登录成功。但是,如果我通过测试尝试分派到另一个位置,或者评估登录的用户是否可以访问给定的资源,它将始终被插件拒绝,因为它们还没有登录。我不是当然,为什么这是,谁能提醒?

例如,这通过:

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

这因为它是由插件拒绝失败:

public function testUserAccess() 
{ 

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

} 

这,我发现似乎仍然被重定向到登陆页面插件不知道用户是否已登录。

任何帮助非常感谢。

回答

3

您所描述的问题在使用全局变量和OOP全局变量(Singleton模式)时发生了很多。

有出自PHPUnit的的作者描述了如何避免使用依赖注入,什么其他的可能性,你已经有了和文章,因为它是非常的描述,我建议你读它:) http://sebastian-bergmann.de/archives/882-Testing-Code-That-Uses-Singletons.html

作为一个丑陋的选择(如果你需要一个快速的结果),你可以创建一个Zend_Auth的存根(在链接中描述)并使用PHP 5.3反射API来为你的存根设置Zend_Auth实例变量。

希望帮助(因为这个问题住4H没有其他的答案)

+0

是的 - 谢谢你,似乎是问题。 – 2010-07-28 16:12:07

2

下面是一个创建存根测试过程中替换的ACL插件(或任何插件)的另一种方式。把它放在ControllerTestCase中,并在测试用例setUp中调用它。

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

这样,您的stub preDispatch方法被调用,而这将会绕过您的实际访问控制检查。