2

次のような要素からのみ呼び出されることになっているコントローラーアクションをテストしようとしています。

$notes = $this->requestAction(array(
        'controller' => 'notes'
    ) , array(
        'pass' => array(
            'location' => $requestUrl
        )
    ));

アクション自体には、アクションが「要求された」ことを確認するためのチェックがあります。

public function index() {
    if (!empty($this->params['requested'])) {
        ...
        return $notes;
    } else {
        throw new ForbiddenException();
    }
}

上記のコードをテストするにはどうすればよいですか?以下:

$this->testAction('/notes', array(

                'passed' => array('location'=>'location1'),

                'return' => 'vars'

            ));

ForbiddenExceptionをトリガーします。$ this-> generateを使用してみましたが、$ this->controller->paramsオブジェクトをどのように生成すればよいかわかりません。

4

2 に答える 2

2

返信ありがとうございます@nanoman。しかし、私はもっと簡単な解決策を見つけました(なぜ私が以前にこれについて考えたのか分かりません)。将来の参考のためにここに書いてください。

テストからrequestActionを呼び出すだけです!

function testMytest() {
    $this->controller = $this->generate('Notes', array(
           'components' => array(
                'Auth'
            )
        ));
    $notes = $this->controller->requestAction(array(
        'controller' => 'notes'
    ) , array(
        'pass' => array(
            'location' => 'location1'
        )
    ));
}
于 2013-02-23T15:13:18.323 に答える
0

CakeRequestを使用しているモックオブジェクトを変更する方法はありませんControllerTestCase::_testAction

唯一のチャンスは、サブクラス化して、そこにControllerTestCaseあるメソッドをコピーし、使用するパラメーターまたはオブジェクトを_testAction渡すメソッドにパラメーターを追加することです。CakeRequest以下の実装を参照してください。

テストケースでは、次のように使用します。

$testUrl = '/notes';
$request = $this->getMock('CakeRequest', array('_readInput'), array($testUrl));
$request->addParams(array('requested' => true));
$this->testAction('/notes', array(
    'passed' => array('location'=>'location1'),
    'return' => 'vars',
    'request' => $request
));

MyControllerTestCase

class MyControllerTestCase() {
    protected function _testAction($url = '', $options = array()) {
        $this->vars = $this->result = $this->view = $this->contents = $this->headers = null;

        $options = array_merge(array(
            'data' => array(),
            'method' => 'POST',
            'return' => 'result',
            'request' => null
        ), $options);

        $restore = array('get' => $_GET, 'post' => $_POST);

        $_SERVER['REQUEST_METHOD'] = strtoupper($options['method']);
        if (is_array($options['data'])) {
            if (strtoupper($options['method']) == 'GET') {
                $_GET = $options['data'];
                $_POST = array();
            } else {
                $_POST = $options['data'];
                $_GET = array();
            }
        }

        if($options['request'] instanceof CakeRequest) {
            $request = $options['request'];
        } else {
            $request = $this->getMock('CakeRequest', array('_readInput'), array($url));
        }

        if (is_string($options['data'])) {
            $request->expects($this->any())
                ->method('_readInput')
                ->will($this->returnValue($options['data']));
        }

        $Dispatch = new ControllerTestDispatcher();
        foreach (Router::$routes as $route) {
            if ($route instanceof RedirectRoute) {
                $route->response = $this->getMock('CakeResponse', array('send'));
            }
        }
        $Dispatch->loadRoutes = $this->loadRoutes;
        $Dispatch->parseParams(new CakeEvent('ControllerTestCase', $Dispatch, array('request' => $request)));
        if (!isset($request->params['controller']) && Router::currentRoute()) {
            $this->headers = Router::currentRoute()->response->header();
            return;
        }
        if ($this->_dirtyController) {
            $this->controller = null;
        }

        $plugin = empty($request->params['plugin']) ? '' : Inflector::camelize($request->params['plugin']) . '.';
        if ($this->controller === null && $this->autoMock) {
            $this->generate($plugin . Inflector::camelize($request->params['controller']));
        }
        $params = array();
        if ($options['return'] == 'result') {
            $params['return'] = 1;
            $params['bare'] = 1;
            $params['requested'] = 1;
        }
        $Dispatch->testController = $this->controller;
        $Dispatch->response = $this->getMock('CakeResponse', array('send'));
        $this->result = $Dispatch->dispatch($request, $Dispatch->response, $params);
        $this->controller = $Dispatch->testController;
        $this->vars = $this->controller->viewVars;
        $this->contents = $this->controller->response->body();
        if (isset($this->controller->View)) {
            $this->view = $this->controller->View->fetch('__view_no_layout__');
        }
        $this->_dirtyController = true;
        $this->headers = $Dispatch->response->header();

        $_GET = $restore['get'];
        $_POST = $restore['post'];

        return $this->{$options['return']};
    }
}
于 2013-02-21T09:22:05.333 に答える