2

我怀疑在 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(我得到了重定向器 ok),重定向(它似乎正在重定向 ok ...),错误(但是我到了错误控制器)没有资源,

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

$user = \Zend_Auth::getInstance()->getIdentity();

它失败 ...

如何让重定向器在 Zend Test 中工作?或者也许它不是重定向器的问题?

4

1 回答 1

3

这是一个两部分的问题。首先,重定向器默认exit在重定向后调用 PHP,这会导致 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');)。这会修改请求以指向pluginRedirectorAction()上面显示的错误控制器中的方法。控制器插件中的重定向现在被称为如下:

return $this->redirect(307, '/somewhere/else');

但它不会在routeStartup()方法内工作,因为 ZF 会在此之后立即启动路由器,这将覆盖redirect()方法指定的请求参数。您必须重新设计插件的管道,以调用您的重定向routeShutdown()或其他在调度周期后期调用的方法。(我只在 . 内测试过这个routeShutdown()。)

于 2011-07-12T23:23:05.297 回答