Cakephp 2.3单元测试参数[''要求']

时间:2013-02-13 23:16:20

标签: unit-testing cakephp-2.3

我正在尝试测试一个仅应该从这样的元素调用的控制器动作:

$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对象。

2 个答案:

答案 0 :(得分: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'
        )
    ));
}

答案 1 :(得分:0)

无法修改CakeRequest正在使用的模拟ControllerTestCase::_testAction对象。

你唯一的机会是继承ControllerTestCase,在那里复制_testAction方法,并在传递params或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']};
    }
}