CakePHP
  • Documentation
    • Book
    • API
    • Videos
    • Reporting Security Issues
    • Privacy Policy
    • Logos & Trademarks
  • Business Solutions
  • Swag
  • Road Trip
  • Team
  • Community
    • Community
    • Get Involved
    • Issues (GitHub)
    • Bakery
    • Featured Resources
    • Training
    • Meetups
    • My CakePHP
    • CakeFest
    • Newsletter
    • Linkedin
    • YouTube
    • Facebook
    • Twitter
    • Mastodon
    • Help & Support
    • Forum
    • Stack Overflow
    • Slack
    • Paid Support
CakePHP

C CakePHP 2.10 API

  • Overview
  • Tree
  • Deprecated
  • Version:
    • 2.10
      • 4.2
      • 4.1
      • 4.0
      • 3.9
      • 3.8
      • 3.7
      • 3.6
      • 3.5
      • 3.4
      • 3.3
      • 3.2
      • 3.1
      • 3.0
      • 2.10
      • 2.9
      • 2.8
      • 2.7
      • 2.6
      • 2.5
      • 2.4
      • 2.3
      • 2.2
      • 2.1
      • 2.0
      • 1.3
      • 1.2

Packages

  • Cake
    • Cache
      • Engine
    • Configure
    • Console
      • Command
        • Task
    • Controller
      • Component
        • Acl
        • Auth
    • Core
    • Error
    • Event
    • I18n
    • Log
      • Engine
    • Model
      • Behavior
      • Datasource
        • Database
        • Session
      • Validator
    • Network
      • Email
      • Http
    • Routing
      • Filter
      • Route
    • TestSuite
      • Coverage
      • Fixture
      • Reporter
    • Utility
    • View
      • Helper
  • None

Classes

  • CakeTestCase
  • CakeTestLoader
  • CakeTestRunner
  • CakeTestSuite
  • CakeTestSuiteCommand
  • CakeTestSuiteDispatcher
  • ControllerTestCase
  • ControllerTestDispatcher
  • InterceptContentHelper
  1: <?php
  2: /**
  3:  * ControllerTestCase file
  4:  *
  5:  * CakePHP(tm) Tests <https://book.cakephp.org/2.0/en/development/testing.html>
  6:  * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
  7:  *
  8:  * Licensed under The MIT License
  9:  * For full copyright and license information, please see the LICENSE.txt
 10:  * Redistributions of files must retain the above copyright notice
 11:  *
 12:  * @copyright     Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
 13:  * @link          https://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
 14:  * @package       Cake.TestSuite
 15:  * @since         CakePHP(tm) v 2.0
 16:  * @license       https://opensource.org/licenses/mit-license.php MIT License
 17:  */
 18: 
 19: App::uses('Dispatcher', 'Routing');
 20: App::uses('CakeTestCase', 'TestSuite');
 21: App::uses('Router', 'Routing');
 22: App::uses('CakeRequest', 'Network');
 23: App::uses('CakeResponse', 'Network');
 24: App::uses('Helper', 'View');
 25: App::uses('CakeEvent', 'Event');
 26: 
 27: /**
 28:  * ControllerTestDispatcher class
 29:  *
 30:  * @package       Cake.TestSuite
 31:  */
 32: class ControllerTestDispatcher extends Dispatcher {
 33: 
 34: /**
 35:  * The controller to use in the dispatch process
 36:  *
 37:  * @var Controller
 38:  */
 39:     public $testController = null;
 40: 
 41: /**
 42:  * Use custom routes during tests
 43:  *
 44:  * @var bool
 45:  */
 46:     public $loadRoutes = true;
 47: 
 48: /**
 49:  * Returns the test controller
 50:  *
 51:  * @param CakeRequest $request The request instance.
 52:  * @param CakeResponse $response The response instance.
 53:  * @return Controller
 54:  */
 55:     protected function _getController($request, $response) {
 56:         if ($this->testController === null) {
 57:             $this->testController = parent::_getController($request, $response);
 58:         }
 59:         $this->testController->helpers = array_merge(array('InterceptContent'), $this->testController->helpers);
 60:         $this->testController->setRequest($request);
 61:         $this->testController->response = $this->response;
 62:         foreach ($this->testController->Components->loaded() as $component) {
 63:             $object = $this->testController->Components->{$component};
 64:             if (isset($object->response)) {
 65:                 $object->response = $response;
 66:             }
 67:             if (isset($object->request)) {
 68:                 $object->request = $request;
 69:             }
 70:         }
 71:         return $this->testController;
 72:     }
 73: 
 74: /**
 75:  * Loads routes and resets if the test case dictates it should
 76:  *
 77:  * @return void
 78:  */
 79:     protected function _loadRoutes() {
 80:         parent::_loadRoutes();
 81:         if (!$this->loadRoutes) {
 82:             Router::reload();
 83:         }
 84:     }
 85: 
 86: }
 87: 
 88: /**
 89:  * InterceptContentHelper class
 90:  *
 91:  * @package       Cake.TestSuite
 92:  */
 93: class InterceptContentHelper extends Helper {
 94: 
 95: /**
 96:  * Intercepts and stores the contents of the view before the layout is rendered
 97:  *
 98:  * @param string $viewFile The view file
 99:  * @return void
100:  */
101:     public function afterRender($viewFile) {
102:         $this->_View->assign('__view_no_layout__', $this->_View->fetch('content'));
103:         $this->_View->Helpers->unload('InterceptContent');
104:     }
105: 
106: }
107: 
108: /**
109:  * ControllerTestCase class
110:  *
111:  * @package       Cake.TestSuite
112:  * @method        mixed testAction() testAction($url, $options = array())  Lets you do functional tests of a controller action.
113:  */
114: abstract class ControllerTestCase extends CakeTestCase {
115: 
116: /**
117:  * The controller to test in testAction
118:  *
119:  * @var Controller
120:  */
121:     public $controller = null;
122: 
123: /**
124:  * Automatically mock controllers that aren't mocked
125:  *
126:  * @var bool
127:  */
128:     public $autoMock = true;
129: 
130: /**
131:  * Use custom routes during tests
132:  *
133:  * @var bool
134:  */
135:     public $loadRoutes = true;
136: 
137: /**
138:  * The resulting view vars of the last testAction call
139:  *
140:  * @var array
141:  */
142:     public $vars = null;
143: 
144: /**
145:  * The resulting rendered view of the last testAction call
146:  *
147:  * @var string
148:  */
149:     public $view = null;
150: 
151: /**
152:  * The resulting rendered layout+view of the last testAction call
153:  *
154:  * @var string
155:  */
156:     public $contents = null;
157: 
158: /**
159:  * The returned result of the dispatch (requestAction), if any
160:  *
161:  * @var string
162:  */
163:     public $result = null;
164: 
165: /**
166:  * The headers that would have been sent by the action
167:  *
168:  * @var string
169:  */
170:     public $headers = null;
171: 
172: /**
173:  * Flag for checking if the controller instance is dirty.
174:  * Once a test has been run on a controller it should be rebuilt
175:  * to clean up properties.
176:  *
177:  * @var bool
178:  */
179:     protected $_dirtyController = false;
180: 
181: /**
182:  * The class name to use for mocking the response object.
183:  *
184:  * @var string
185:  */
186:     protected $_responseClass = 'CakeResponse';
187: 
188: /**
189:  * Used to enable calling ControllerTestCase::testAction() without the testing
190:  * framework thinking that it's a test case
191:  *
192:  * @param string $name The name of the function
193:  * @param array $arguments Array of arguments
194:  * @return mixed The return of _testAction.
195:  * @throws BadMethodCallException when you call methods that don't exist.
196:  */
197:     public function __call($name, $arguments) {
198:         if ($name === 'testAction') {
199:             return call_user_func_array(array($this, '_testAction'), $arguments);
200:         }
201:         throw new BadMethodCallException("Method '{$name}' does not exist.");
202:     }
203: 
204: /**
205:  * Lets you do functional tests of a controller action.
206:  *
207:  * ### Options:
208:  *
209:  * - `data` Will be used as the request data. If the `method` is GET,
210:  *   data will be used a GET params. If the `method` is POST, it will be used
211:  *   as POST data. By setting `$options['data']` to a string, you can simulate XML or JSON
212:  *   payloads to your controllers allowing you to test REST webservices.
213:  * - `method` POST or GET. Defaults to POST.
214:  * - `return` Specify the return type you want. Choose from:
215:  *     - `vars` Get the set view variables.
216:  *     - `view` Get the rendered view, without a layout.
217:  *     - `contents` Get the rendered view including the layout.
218:  *     - `result` Get the return value of the controller action. Useful
219:  *       for testing requestAction methods.
220:  *
221:  * @param string|array $url The URL to test.
222:  * @param array $options See options
223:  * @return mixed The specified return type.
224:  * @triggers ControllerTestCase $Dispatch, array('request' => $request)
225:  */
226:     protected function _testAction($url, $options = array()) {
227:         $this->vars = $this->result = $this->view = $this->contents = $this->headers = null;
228: 
229:         $options += array(
230:             'data' => array(),
231:             'method' => 'POST',
232:             'return' => 'result'
233:         );
234: 
235:         if (is_array($url)) {
236:             $url = Router::url($url);
237:         }
238: 
239:         $restore = array('get' => $_GET, 'post' => $_POST);
240: 
241:         $_SERVER['REQUEST_METHOD'] = strtoupper($options['method']);
242:         if (is_array($options['data'])) {
243:             if (strtoupper($options['method']) === 'GET') {
244:                 $_GET = $options['data'];
245:                 $_POST = array();
246:             } else {
247:                 $_POST = $options['data'];
248:                 $_GET = array();
249:             }
250:         }
251: 
252:         if (strpos($url, '?') !== false) {
253:             list($url, $query) = explode('?', $url, 2);
254:             parse_str($query, $queryArgs);
255:             $_GET += $queryArgs;
256:         }
257: 
258:         $_SERVER['REQUEST_URI'] = $url;
259:         /** @var CakeRequest|PHPUnit_Framework_MockObject_MockObject $request */
260:         $request = $this->getMock('CakeRequest', array('_readInput'));
261: 
262:         if (is_string($options['data'])) {
263:             $request->expects($this->any())
264:                 ->method('_readInput')
265:                 ->will($this->returnValue($options['data']));
266:         }
267: 
268:         $Dispatch = $this->_createDispatcher();
269:         foreach (Router::$routes as $route) {
270:             if ($route instanceof RedirectRoute) {
271:                 $route->response = $this->getMock('CakeResponse', array('send'));
272:             }
273:         }
274:         $Dispatch->loadRoutes = $this->loadRoutes;
275:         $Dispatch->parseParams(new CakeEvent('ControllerTestCase', $Dispatch, array('request' => $request)));
276:         if (!isset($request->params['controller']) && Router::currentRoute()) {
277:             $this->headers = Router::currentRoute()->response->header();
278:             return null;
279:         }
280:         if ($this->_dirtyController) {
281:             $this->controller = null;
282:         }
283: 
284:         $plugin = empty($request->params['plugin']) ? '' : Inflector::camelize($request->params['plugin']) . '.';
285:         if ($this->controller === null && $this->autoMock) {
286:             $this->generate($plugin . Inflector::camelize($request->params['controller']));
287:         }
288:         $params = array();
289:         if ($options['return'] === 'result') {
290:             $params['return'] = 1;
291:             $params['bare'] = 1;
292:             $params['requested'] = 1;
293:         }
294:         $Dispatch->testController = $this->controller;
295:         $Dispatch->response = $this->getMock($this->_responseClass, array('send', '_clearBuffer'));
296:         $this->result = $Dispatch->dispatch($request, $Dispatch->response, $params);
297: 
298:         // Clear out any stored requests.
299:         while (Router::getRequest()) {
300:             Router::popRequest();
301:         }
302: 
303:         $this->controller = $Dispatch->testController;
304:         $this->vars = $this->controller->viewVars;
305:         $this->contents = $this->controller->response->body();
306:         if (isset($this->controller->View)) {
307:             $this->view = $this->controller->View->fetch('__view_no_layout__');
308:         }
309:         $this->_dirtyController = true;
310:         $this->headers = $Dispatch->response->header();
311: 
312:         $_GET = $restore['get'];
313:         $_POST = $restore['post'];
314: 
315:         return $this->{$options['return']};
316:     }
317: 
318: /**
319:  * Creates the test dispatcher class
320:  *
321:  * @return Dispatcher
322:  */
323:     protected function _createDispatcher() {
324:         return new ControllerTestDispatcher();
325:     }
326: 
327: /**
328:  * Generates a mocked controller and mocks any classes passed to `$mocks`. By
329:  * default, `_stop()` is stubbed as is sending the response headers, so to not
330:  * interfere with testing.
331:  *
332:  * ### Mocks:
333:  *
334:  * - `methods` Methods to mock on the controller. `_stop()` is mocked by default
335:  * - `models` Models to mock. Models are added to the ClassRegistry so any
336:  *   time they are instantiated the mock will be created. Pass as key value pairs
337:  *   with the value being specific methods on the model to mock. If `true` or
338:  *   no value is passed, the entire model will be mocked.
339:  * - `components` Components to mock. Components are only mocked on this controller
340:  *   and not within each other (i.e., components on components)
341:  *
342:  * @param string $controller Controller name
343:  * @param array $mocks List of classes and methods to mock
344:  * @return Controller Mocked controller
345:  * @throws MissingControllerException When controllers could not be created.
346:  * @throws MissingComponentException When components could not be created.
347:  */
348:     public function generate($controller, $mocks = array()) {
349:         list($plugin, $controller) = pluginSplit($controller);
350:         if ($plugin) {
351:             App::uses($plugin . 'AppController', $plugin . '.Controller');
352:             $plugin .= '.';
353:         }
354:         App::uses($controller . 'Controller', $plugin . 'Controller');
355:         if (!class_exists($controller . 'Controller')) {
356:             throw new MissingControllerException(array(
357:                 'class' => $controller . 'Controller',
358:                 'plugin' => substr($plugin, 0, -1)
359:             ));
360:         }
361:         ClassRegistry::flush();
362: 
363:         $mocks = array_merge_recursive(array(
364:             'methods' => array('_stop'),
365:             'models' => array(),
366:             'components' => array()
367:         ), (array)$mocks);
368: 
369:         list($plugin, $name) = pluginSplit($controller);
370:         /** @var Controller|PHPUnit_Framework_MockObject_MockObject $controllerObj */
371:         $controllerObj = $this->getMock($name . 'Controller', $mocks['methods'], array(), '', false);
372:         $controllerObj->name = $name;
373:         /** @var CakeRequest|PHPUnit_Framework_MockObject_MockObject $request */
374:         $request = $this->getMock('CakeRequest');
375:         /** @var CakeResponse|PHPUnit_Framework_MockObject_MockObject $response */
376:         $response = $this->getMock($this->_responseClass, array('_sendHeader'));
377:         $controllerObj->__construct($request, $response);
378:         $controllerObj->Components->setController($controllerObj);
379: 
380:         $config = ClassRegistry::config('Model');
381:         foreach ($mocks['models'] as $model => $methods) {
382:             if (is_string($methods)) {
383:                 $model = $methods;
384:                 $methods = true;
385:             }
386:             if ($methods === true) {
387:                 $methods = array();
388:             }
389:             $this->getMockForModel($model, $methods, $config);
390:         }
391: 
392:         foreach ($mocks['components'] as $component => $methods) {
393:             if (is_string($methods)) {
394:                 $component = $methods;
395:                 $methods = true;
396:             }
397:             if ($methods === true) {
398:                 $methods = array();
399:             }
400:             $config = isset($controllerObj->components[$component]) ? $controllerObj->components[$component] : array();
401:             if (isset($config['className'])) {
402:                 $alias = $component;
403:                 $component = $config['className'];
404:             }
405:             list($plugin, $name) = pluginSplit($component, true);
406:             if (!isset($alias)) {
407:                 $alias = $name;
408:             }
409:             $componentClass = $name . 'Component';
410:             App::uses($componentClass, $plugin . 'Controller/Component');
411:             if (!class_exists($componentClass)) {
412:                 throw new MissingComponentException(array(
413:                     'class' => $componentClass
414:                 ));
415:             }
416:             /** @var Component|PHPUnit_Framework_MockObject_MockObject $componentObj */
417:             $componentObj = $this->getMock($componentClass, $methods, array($controllerObj->Components, $config));
418:             $controllerObj->Components->set($alias, $componentObj);
419:             $controllerObj->Components->enable($alias);
420:             unset($alias);
421:         }
422: 
423:         $controllerObj->constructClasses();
424:         $this->_dirtyController = false;
425: 
426:         $this->controller = $controllerObj;
427:         return $this->controller;
428:     }
429: 
430: /**
431:  * Unsets some properties to free memory.
432:  *
433:  * @return void
434:  */
435:     public function tearDown() {
436:         parent::tearDown();
437:         unset(
438:             $this->contents,
439:             $this->controller,
440:             $this->headers,
441:             $this->result,
442:             $this->view,
443:             $this->vars
444:         );
445:     }
446: }
447: 
OpenHub
Rackspace
Rackspace
  • Business Solutions
  • Showcase
  • Documentation
  • Book
  • API
  • Videos
  • Reporting Security Issues
  • Privacy Policy
  • Logos & Trademarks
  • Community
  • Get Involved
  • Issues (GitHub)
  • Bakery
  • Featured Resources
  • Training
  • Meetups
  • My CakePHP
  • CakeFest
  • Newsletter
  • Linkedin
  • YouTube
  • Facebook
  • Twitter
  • Mastodon
  • Help & Support
  • Forum
  • Stack Overflow
  • Slack
  • Paid Support

Generated using CakePHP API Docs