Zend framework Zend_测试与测试;ACL的控制器插件(重定向)

Zend framework Zend_测试与测试;ACL的控制器插件(重定向),zend-framework,zend-acl,zend-controller-plugin,Zend Framework,Zend Acl,Zend Controller Plugin,我怀疑在Zend测试中使用控制器插件重定向时有问题 我有一个控制器插件,就像我把echo语句用于调试一样。我有代码重定向到登录,如果用户没有登录 if (!$auth->hasIdentity()) { echo 'no id, '; // redirect to login page $req->setDispatched(true); $redirector = Zend_Controller_Action_HelperBroker::getStaticHelpe

我怀疑在Zend测试中使用控制器插件重定向时有问题

我有一个控制器插件,就像我把echo语句用于调试一样。我有代码重定向到登录,如果用户没有登录

if (!$auth->hasIdentity()) {
  echo 'no id, ';
  // redirect to login page
  $req->setDispatched(true);
  $redirector = Zend_Controller_Action_HelperBroker::getStaticHelper('redirector');echo 'got redir, ';
  $redirector->gotoUrl('/auth/login?returnUrl=' . urlencode($req->getRequestUri()));echo 'redirecting, ';
} ...
我发现当单元测试时,例如

$this->dispatch('/projects');
我得到的结果是

项目(确定我请求了项目页面/控制器),没有id(确定,我没有登录),得到了redir(我得到了重定向器确定),重定向(似乎是重定向确定…),错误(但我得到了错误控制器)没有资源

我访问错误控制器的原因似乎是我仍然访问了项目/索引页面。在索引操作中,我假设用户已登录。但是当它试图获取登录用户时

$user = \Zend_Auth::getInstance()->getIdentity();
它失败了


如何让重定向器在Zend测试中工作?或者它可能不是重定向器的问题

这是一个由两部分组成的问题。首先,重定向程序默认在重定向后调用PHP的
退出
,这会导致Zend_测试停止执行。在您的测试中,您必须配置重定向器才能不这样做。大概是这样的:

$redirector = new Zend_Controller_Action_Helper_Redirector();
if (APPLICATION_ENV == 'testing') {
    $redirector->setExit(false);
}
$redirector->gotoUrl("/blah/blah");
return $this->redirect(307, '/somewhere/else');
但是控制器插件的问题是,在使用重定向器之后,没有办法阻止Zend Framework进入调度循环并尝试执行动作方法。我在各种形式的帖子中读到过(不记得是在什么地方),这是Zend框架中的一个已知问题,开发人员正计划解决这个问题。现在,我通过在我的错误控制器中添加这样的方法来解决这个问题:

public function pluginRedirectorAction() {
    $this->_helper->layout()->disableLayout();
    $this->_helper->viewRenderer->setNoRender();

    $code = $this->_getParam('code');
    $uri = $this->_getParam('uri');

    if (APPLICATION_ENV == 'testing') {
        $this->_helper->redirector->setExit(false);
    }
    $this->_helper->redirector->setCode($code);
    $this->_helper->redirector->gotoUrl($uri);
}
然后在我的控制器插件中,我有一个调用重定向的自定义方法:

protected function redirect($code, $uri) {
    $redirector = new Zend_Controller_Action_Helper_Redirector();

    if (APPLICATION_ENV == 'testing') {
        $request = $this->getRequest();
        $request->setModuleName('default');
        $request->setControllerName('error');
        $request->setActionName('plugin-redirector');
        $request->setParam('code', $code);  
        $request->setParam('uri', $uri);

        $redirector->setExit(false);
    }

    $redirector->setCode($code);
    $redirector->gotoUrl($uri);
}
通过这样做,您可以将对重定向器的实际调用移动到应用程序的控制器层,从而使单元测试能够正常工作(也称为
$this->assertRedirectTo('/blah/blah');
),这会修改指向上面所示错误控制器中的
pluginRedirectorAction()
方法的请求。控制器插件中的重定向现在称为:

$redirector = new Zend_Controller_Action_Helper_Redirector();
if (APPLICATION_ENV == 'testing') {
    $redirector->setExit(false);
}
$redirector->gotoUrl("/blah/blah");
return $this->redirect(307, '/somewhere/else');
但是它在
routeStartup()
方法中不起作用,因为ZF在这之后立即启动路由器,这将覆盖
重定向()
方法指定的请求参数。您必须重新设计插件的管道,以便从
routeShutdown()
调用重定向,或者在调度周期的后期调用其他方法。(我只在
routeShutdown()
中对此进行了测试)