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なし(OK、ログインしていません)、redir(リダイレクターを取得しました)、リダイレクト(リダイレクトしているようです...)、エラー(しかしエラーコントローラに到達しました)リソースがありません、

エラーコントローラにたどり着いた理由は、まだプロジェクト/インデックスページにたどり着いたからです。インデックスアクションでは、ユーザーがログインしていると想定しました。しかし、ログインしているユーザーを取得しようとすると

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

失敗します...

Zend Testでリダイレクタを機能させるにはどうすればよいですか?それとも、リダイレクタの問題ではないでしょうか?

4

1 に答える 1

3

これは2つの部分からなる問題です。まず、リダイレクタはデフォルトで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 に答える