/** * Tests an action using the controller itself and skipping the dispatcher, and * returning the view vars. * * Since `CakeTestCase::testAction` was causing so many problems and is * incredibly slow, it is overwritten here to go about it a bit differently. * Import `ExtendedTestCase` from 'Lib' and extend test cases using `ExtendedTestCase` * instead to gain this functionality. * * For backwards compatibility with the original `CakeTestCase::testAction`, set * `testController` to `null`. * * ### Options: * - `data` Data to pass to the controller * * ### Limitations: * - only reinstantiates the default model * - not 100% complete, i.e., some callbacks may not be fired like they would * if regularly called through the dispatcher * * @param string $url The url to test * @param array $options A list of options * @return array The view vars * @link http://mark-story.com/posts/view/testing-cakephp-controllers-the-hard-way * @link http://mark-story.com/posts/view/testing-cakephp-controllers-mock-objects-edition * @link http://www.42pixels.com/blog/testing-controllers-the-slightly-less-hard-way */ function testAction($url = '', $options = array()) { if (is_null($this->testController)) { return parent::testAction($url, $options); } $Controller = $this->testController; // reset parameters ClassRegistry::flush(); $Controller->passedArgs = array(); $Controller->params = array(); $Controller->url = null; $Controller->action = null; $Controller->viewVars = array(); $keys = ClassRegistry::keys(); foreach ($keys as $key) { if (is_a(ClassRegistry::getObject(Inflector::camelize($key)), 'Model')) { ClassRegistry::getObject(Inflector::camelize($key))->create(false); } } $Controller->Session->delete('Message'); $Controller->activeUser = null; $default = array('data' => array(), 'method' => 'post'); $options = array_merge($default, $options); // set up the controller based on the url $urlParams = Router::parse($url); $extra = array_diff_key($options, array('data' => null, 'method' => null, 'return' => null)); $urlParams = array_merge($urlParams, $extra); $action = $urlParams['action']; $prefix = null; $urlParams['url']['url'] = $url; if (strtolower($options['method']) == 'get') { $urlParams['url'] = array_merge($options['data'], $urlParams['url']); } else { $Controller->data = $options['data']; } if (isset($urlParams['prefix'])) { $action = $urlParams['prefix'] . '_' . $action; $prefix = $urlParams['prefix'] . '/'; } $Controller->passedArgs = $urlParams['named']; $Controller->params = $urlParams; $Controller->url = $urlParams; $Controller->action = $prefix . $urlParams['plugin'] . '/' . $urlParams['controller'] . '/' . $urlParams['action']; // only initialize the components once if ($this->_componentsInitialized === false) { $this->_componentsInitialized = true; $Controller->Component->initialize($Controller); } $Controller->beforeFilter(); $Controller->Component->startup($Controller); call_user_func_array(array(&$Controller, $action), $urlParams['pass']); $Controller->beforeRender(); $Controller->Component->triggerCallback('beforeRender', $Controller); return $Controller->viewVars; }
/** * Tests an action using the controller itself and skipping the dispatcher, and * returning the view vars. * * Since `CakeTestCase::testAction` was causing so many problems and is * incredibly slow, it is overwritten here to go about it a bit differently. * Import `CoreTestCase` from 'Lib' and extend test cases using `CoreTestCase` * instead to gain this functionality. * * For backwards compatibility with the original `CakeTestCase::testAction`, set * `testController` to `null`. * * ### Options: * - `data` Data to pass to the controller * * ### Limitations: * - only reinstantiates the default model * - not 100% complete, i.e., some callbacks may not be fired like they would * if regularly called through the dispatcher * * @param string $url The url to test * @param array $options A list of options * @return array The view vars * @link http://mark-story.com/posts/view/testing-cakephp-controllers-the-hard-way */ public function testAction($url = '', $options = array()) { if (is_null($this->testController)) { return parent::testAction($url, $options); } $Controller = $this->testController; // reset parameters $Controller->passedArgs = array(); $Controller->params = array(); $Controller->url = null; $Controller->action = null; $Controller->viewVars = array(); $keys = ClassRegistry::keys(); foreach ($keys as $key) { if (is_a(ClassRegistry::getObject(Inflector::camelize($key)), 'Model')) { ClassRegistry::getObject(Inflector::camelize($key))->create(false); } } $Controller->Session->delete('Message'); $Controller->activeUser = null; $default = array('data' => array(), 'method' => 'post'); $options = array_merge($default, $options); // set up the controller based on the url $urlParams = Router::parse($url); if (stripos('http', $url) === false) { $url = 'http://localhost/' . ltrim($url, '/'); } parse_str(parse_url($url, PHP_URL_QUERY), $queryParams); if (!isset($urlParams['url'])) { $urlParams['url'] = array(); } $urlParams['url'] = array_merge($urlParams['url'], $queryParams); if (strtolower($options['method']) == 'get') { $urlParams['url'] = array_merge($options['data'], $urlParams['url']); } else { $Controller->data = $options['data']; } $Controller->passedArgs = $urlParams['named']; $Controller->params = $urlParams; $Controller->params['url']['url'] = $url; $Controller->url = $urlParams; $Controller->action = $urlParams['plugin'] . '/' . $urlParams['controller'] . '/' . $urlParams['action']; $Controller->Component->initialize($Controller); if (isset($Controller->Toolbar)) { $Controller->Toolbar->enabled = false; } // configure auth if (isset($Controller->Auth)) { $Controller->Auth->initialize($Controller); if (!$Controller->Session->check('Auth.User') && !$Controller->Session->check('User')) { $this->su(); } } // configure acl if (isset($Controller->Acl)) { $core =& Core::getInstance(); $core->Acl = new MockAclComponent(); $core->Acl->__construct(); $core->Acl->enabled = true; $core->Acl->setReturnValue('check', true); } $Controller->beforeFilter(); $Controller->Component->startup($Controller); call_user_func_array(array(&$Controller, $urlParams['action']), $urlParams['pass']); $Controller->beforeRender(); $Controller->Component->triggerCallback('beforeRender', $Controller); // trick debugkit into skipping its __destruct method which clutters up the response if (class_exists('DebugKitDebugger')) { $_debugkit =& DebugKitDebugger::getInstance(); $_debugkit->__benchmarks = null; } return $Controller->viewVars; }
/** * testAction method * * Automatically set request info * * @param mixed $url * @param array $params array() * @return void * @access public */ public function testAction($url, $params = array()) { static $referer = null; Configure::write('Testing.url', $url); Configure::write('Testing.referer', $referer); Configure::write('App.base', '/'); Configure::write('App.baseUrl', '/'); Router::setRequestInfo(array(array('controller' => 'test_swiss_army', 'action' => 'never used', 'url' => array('url' => $url)), array('base' => '/', 'here' => $url, 'webroot' => '/', 'passedArgs' => array(), 'namedArgs' => array()))); $return = parent::testAction($url, $params); $referer = $url; return $return; }