我怀疑在Zend Test中使用控制器插件重定向时出现问题?
我有一个像http://pastie.org/1422639这样的控制器插件我已经把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 Test中使用重定向器?或者它可能不是重定向器的问题?
答案 0 :(得分:3)
这是一个由两部分组成的问题。首先,重定向器在重定向后默认调用PHP的exit
,这会导致Zend_Test停止执行。在测试中,您必须配置重定向器不要这样做。像这样:
$redirector = new Zend_Controller_Action_Helper_Redirector();
if (APPLICATION_ENV == 'testing') {
$redirector->setExit(false);
}
$redirector->gotoUrl("/blah/blah");
但是控制器插件中的问题是在使用重定向器之后,无法阻止Zend Framework进入调度循环并尝试执行动作方法。我已经阅读了各种形式的帖子(不记得在哪里随便),这是开发人员计划解决的Zend Framework中的一个已知问题。现在,我通过在我的错误控制器中添加这样的方法来解决这个问题:
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');
。)这会将请求修改为指向{{1上面显示的错误控制器中的方法。控制器插件中的重定向现在称为:
pluginRedirectorAction()
但它不会在return $this->redirect(307, '/somewhere/else');
方法中起作用,因为ZF会在此之后立即启动路由器,这将覆盖routeStartup()
方法指定的请求参数。您必须重新设计插件的管道,以便从redirect()
调用重定向或者在调度周期后期调用的其他方法。 (我只在routeShutdown()
内进行了测试。)