CakeTestCase.php 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713
  1. <?php
  2. /**
  3. * CakeTestCase file
  4. *
  5. * PHP 5
  6. *
  7. * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
  8. * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  9. *
  10. * Licensed under The MIT License
  11. * For full copyright and license information, please see the LICENSE.txt
  12. * Redistributions of files must retain the above copyright notice
  13. *
  14. * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  15. * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
  16. * @package Cake.TestSuite
  17. * @since CakePHP(tm) v 1.2.0.4667
  18. * @license http://www.opensource.org/licenses/mit-license.php MIT License
  19. */
  20. App::uses('CakeFixtureManager', 'TestSuite/Fixture');
  21. App::uses('CakeTestFixture', 'TestSuite/Fixture');
  22. /**
  23. * CakeTestCase class
  24. *
  25. * @package Cake.TestSuite
  26. */
  27. abstract class CakeTestCase extends PHPUnit_Framework_TestCase {
  28. /**
  29. * The class responsible for managing the creation, loading and removing of fixtures
  30. *
  31. * @var CakeFixtureManager
  32. */
  33. public $fixtureManager = null;
  34. /**
  35. * By default, all fixtures attached to this class will be truncated and reloaded after each test.
  36. * Set this to false to handle manually
  37. *
  38. * @var array
  39. */
  40. public $autoFixtures = true;
  41. /**
  42. * Control table create/drops on each test method.
  43. *
  44. * Set this to false to avoid tables to be dropped if they already exist
  45. * between each test method. Tables will still be dropped at the
  46. * end of each test runner execution.
  47. *
  48. * @var boolean
  49. */
  50. public $dropTables = true;
  51. /**
  52. * Configure values to restore at end of test.
  53. *
  54. * @var array
  55. */
  56. protected $_configure = array();
  57. /**
  58. * Path settings to restore at the end of the test.
  59. *
  60. * @var array
  61. */
  62. protected $_pathRestore = array();
  63. /**
  64. * Runs the test case and collects the results in a TestResult object.
  65. * If no TestResult object is passed a new one will be created.
  66. * This method is run for each test method in this class
  67. *
  68. * @param PHPUnit_Framework_TestResult $result
  69. * @return PHPUnit_Framework_TestResult
  70. * @throws InvalidArgumentException
  71. */
  72. public function run(PHPUnit_Framework_TestResult $result = null) {
  73. if (!empty($this->fixtureManager)) {
  74. $this->fixtureManager->load($this);
  75. }
  76. $result = parent::run($result);
  77. if (!empty($this->fixtureManager)) {
  78. $this->fixtureManager->unload($this);
  79. }
  80. return $result;
  81. }
  82. /**
  83. * Called when a test case method is about to start (to be overridden when needed.)
  84. *
  85. * @param string $method Test method about to get executed.
  86. * @return void
  87. */
  88. public function startTest($method) {
  89. }
  90. /**
  91. * Called when a test case method has been executed (to be overridden when needed.)
  92. *
  93. * @param string $method Test method about that was executed.
  94. * @return void
  95. */
  96. public function endTest($method) {
  97. }
  98. /**
  99. * Overrides SimpleTestCase::skipIf to provide a boolean return value
  100. *
  101. * @param boolean $shouldSkip
  102. * @param string $message
  103. * @return boolean
  104. */
  105. public function skipIf($shouldSkip, $message = '') {
  106. if ($shouldSkip) {
  107. $this->markTestSkipped($message);
  108. }
  109. return $shouldSkip;
  110. }
  111. /**
  112. * Setup the test case, backup the static object values so they can be restored.
  113. * Specifically backs up the contents of Configure and paths in App if they have
  114. * not already been backed up.
  115. *
  116. * @return void
  117. */
  118. public function setUp() {
  119. parent::setUp();
  120. if (empty($this->_configure)) {
  121. $this->_configure = Configure::read();
  122. }
  123. if (empty($this->_pathRestore)) {
  124. $this->_pathRestore = App::paths();
  125. }
  126. if (class_exists('Router', false)) {
  127. Router::reload();
  128. }
  129. }
  130. /**
  131. * teardown any static object changes and restore them.
  132. *
  133. * @return void
  134. */
  135. public function tearDown() {
  136. parent::tearDown();
  137. App::build($this->_pathRestore, App::RESET);
  138. if (class_exists('ClassRegistry', false)) {
  139. ClassRegistry::flush();
  140. }
  141. if (!empty($this->_configure)) {
  142. Configure::clear();
  143. Configure::write($this->_configure);
  144. }
  145. if (isset($_GET['debug']) && $_GET['debug']) {
  146. ob_flush();
  147. }
  148. }
  149. /**
  150. * See CakeTestSuiteDispatcher::date()
  151. *
  152. * @param string $format format to be used.
  153. * @return string
  154. */
  155. public static function date($format = 'Y-m-d H:i:s') {
  156. return CakeTestSuiteDispatcher::date($format);
  157. }
  158. // @codingStandardsIgnoreStart PHPUnit overrides don't match CakePHP
  159. /**
  160. * Announces the start of a test.
  161. *
  162. * @return void
  163. */
  164. protected function assertPreConditions() {
  165. parent::assertPreConditions();
  166. $this->startTest($this->getName());
  167. }
  168. /**
  169. * Announces the end of a test.
  170. *
  171. * @return void
  172. */
  173. protected function assertPostConditions() {
  174. parent::assertPostConditions();
  175. $this->endTest($this->getName());
  176. }
  177. // @codingStandardsIgnoreEnd
  178. /**
  179. * Chooses which fixtures to load for a given test
  180. *
  181. * @param string $fixture Each parameter is a model name that corresponds to a
  182. * fixture, i.e. 'Post', 'Author', etc.
  183. * @return void
  184. * @see CakeTestCase::$autoFixtures
  185. * @throws Exception when no fixture manager is available.
  186. */
  187. public function loadFixtures() {
  188. if (empty($this->fixtureManager)) {
  189. throw new Exception(__d('cake_dev', 'No fixture manager to load the test fixture'));
  190. }
  191. $args = func_get_args();
  192. foreach ($args as $class) {
  193. $this->fixtureManager->loadSingle($class, null, $this->dropTables);
  194. }
  195. }
  196. /**
  197. * Assert text equality, ignoring differences in newlines.
  198. * Helpful for doing cross platform tests of blocks of text.
  199. *
  200. * @param string $expected The expected value.
  201. * @param string $result The actual value.
  202. * @param message The message to use for failure.
  203. * @return boolean
  204. */
  205. public function assertTextNotEquals($expected, $result, $message = '') {
  206. $expected = str_replace(array("\r\n", "\r"), "\n", $expected);
  207. $result = str_replace(array("\r\n", "\r"), "\n", $result);
  208. return $this->assertNotEquals($expected, $result, $message);
  209. }
  210. /**
  211. * Assert text equality, ignoring differences in newlines.
  212. * Helpful for doing cross platform tests of blocks of text.
  213. *
  214. * @param string $expected The expected value.
  215. * @param string $result The actual value.
  216. * @param message The message to use for failure.
  217. * @return boolean
  218. */
  219. public function assertTextEquals($expected, $result, $message = '') {
  220. $expected = str_replace(array("\r\n", "\r"), "\n", $expected);
  221. $result = str_replace(array("\r\n", "\r"), "\n", $result);
  222. return $this->assertEquals($expected, $result, $message);
  223. }
  224. /**
  225. * Asserts that a string starts with a given prefix, ignoring differences in newlines.
  226. * Helpful for doing cross platform tests of blocks of text.
  227. *
  228. * @param string $prefix
  229. * @param string $string
  230. * @param string $message
  231. * @return boolean
  232. */
  233. public function assertTextStartsWith($prefix, $string, $message = '') {
  234. $prefix = str_replace(array("\r\n", "\r"), "\n", $prefix);
  235. $string = str_replace(array("\r\n", "\r"), "\n", $string);
  236. return $this->assertStringStartsWith($prefix, $string, $message);
  237. }
  238. /**
  239. * Asserts that a string starts not with a given prefix, ignoring differences in newlines.
  240. * Helpful for doing cross platform tests of blocks of text.
  241. *
  242. * @param string $prefix
  243. * @param string $string
  244. * @param string $message
  245. * @return boolean
  246. */
  247. public function assertTextStartsNotWith($prefix, $string, $message = '') {
  248. $prefix = str_replace(array("\r\n", "\r"), "\n", $prefix);
  249. $string = str_replace(array("\r\n", "\r"), "\n", $string);
  250. return $this->assertStringStartsNotWith($prefix, $string, $message);
  251. }
  252. /**
  253. * Asserts that a string ends with a given prefix, ignoring differences in newlines.
  254. * Helpful for doing cross platform tests of blocks of text.
  255. *
  256. * @param string $suffix
  257. * @param string $string
  258. * @param string $message
  259. * @return boolean
  260. */
  261. public function assertTextEndsWith($suffix, $string, $message = '') {
  262. $suffix = str_replace(array("\r\n", "\r"), "\n", $suffix);
  263. $string = str_replace(array("\r\n", "\r"), "\n", $string);
  264. return $this->assertStringEndsWith($suffix, $string, $message);
  265. }
  266. /**
  267. * Asserts that a string ends not with a given prefix, ignoring differences in newlines.
  268. * Helpful for doing cross platform tests of blocks of text.
  269. *
  270. * @param string $suffix
  271. * @param string $string
  272. * @param string $message
  273. * @return boolean
  274. */
  275. public function assertTextEndsNotWith($suffix, $string, $message = '') {
  276. $suffix = str_replace(array("\r\n", "\r"), "\n", $suffix);
  277. $string = str_replace(array("\r\n", "\r"), "\n", $string);
  278. return $this->assertStringEndsNotWith($suffix, $string, $message);
  279. }
  280. /**
  281. * Assert that a string contains another string, ignoring differences in newlines.
  282. * Helpful for doing cross platform tests of blocks of text.
  283. *
  284. * @param string $needle
  285. * @param string $haystack
  286. * @param string $message
  287. * @param boolean $ignoreCase
  288. * @return boolean
  289. */
  290. public function assertTextContains($needle, $haystack, $message = '', $ignoreCase = false) {
  291. $needle = str_replace(array("\r\n", "\r"), "\n", $needle);
  292. $haystack = str_replace(array("\r\n", "\r"), "\n", $haystack);
  293. return $this->assertContains($needle, $haystack, $message, $ignoreCase);
  294. }
  295. /**
  296. * Assert that a text doesn't contain another text, ignoring differences in newlines.
  297. * Helpful for doing cross platform tests of blocks of text.
  298. *
  299. * @param string $needle
  300. * @param string $haystack
  301. * @param string $message
  302. * @param boolean $ignoreCase
  303. * @return boolean
  304. */
  305. public function assertTextNotContains($needle, $haystack, $message = '', $ignoreCase = false) {
  306. $needle = str_replace(array("\r\n", "\r"), "\n", $needle);
  307. $haystack = str_replace(array("\r\n", "\r"), "\n", $haystack);
  308. return $this->assertNotContains($needle, $haystack, $message, $ignoreCase);
  309. }
  310. /**
  311. * Takes an array $expected and generates a regex from it to match the provided $string.
  312. * Samples for $expected:
  313. *
  314. * Checks for an input tag with a name attribute (contains any non-empty value) and an id
  315. * attribute that contains 'my-input':
  316. * array('input' => array('name', 'id' => 'my-input'))
  317. *
  318. * Checks for two p elements with some text in them:
  319. * array(
  320. * array('p' => true),
  321. * 'textA',
  322. * '/p',
  323. * array('p' => true),
  324. * 'textB',
  325. * '/p'
  326. * )
  327. *
  328. * You can also specify a pattern expression as part of the attribute values, or the tag
  329. * being defined, if you prepend the value with preg: and enclose it with slashes, like so:
  330. * array(
  331. * array('input' => array('name', 'id' => 'preg:/FieldName\d+/')),
  332. * 'preg:/My\s+field/'
  333. * )
  334. *
  335. * Important: This function is very forgiving about whitespace and also accepts any
  336. * permutation of attribute order. It will also allow whitespace between specified tags.
  337. *
  338. * @param string $string An HTML/XHTML/XML string
  339. * @param array $expected An array, see above
  340. * @param string $message SimpleTest failure output string
  341. * @return boolean
  342. */
  343. public function assertTags($string, $expected, $fullDebug = false) {
  344. $regex = array();
  345. $normalized = array();
  346. foreach ((array)$expected as $key => $val) {
  347. if (!is_numeric($key)) {
  348. $normalized[] = array($key => $val);
  349. } else {
  350. $normalized[] = $val;
  351. }
  352. }
  353. $i = 0;
  354. foreach ($normalized as $tags) {
  355. if (!is_array($tags)) {
  356. $tags = (string)$tags;
  357. }
  358. $i++;
  359. if (is_string($tags) && $tags{0} === '<') {
  360. $tags = array(substr($tags, 1) => array());
  361. } elseif (is_string($tags)) {
  362. $tagsTrimmed = preg_replace('/\s+/m', '', $tags);
  363. if (preg_match('/^\*?\//', $tags, $match) && $tagsTrimmed !== '//') {
  364. $prefix = array(null, null);
  365. if ($match[0] === '*/') {
  366. $prefix = array('Anything, ', '.*?');
  367. }
  368. $regex[] = array(
  369. sprintf('%sClose %s tag', $prefix[0], substr($tags, strlen($match[0]))),
  370. sprintf('%s<[\s]*\/[\s]*%s[\s]*>[\n\r]*', $prefix[1], substr($tags, strlen($match[0]))),
  371. $i,
  372. );
  373. continue;
  374. }
  375. if (!empty($tags) && preg_match('/^preg\:\/(.+)\/$/i', $tags, $matches)) {
  376. $tags = $matches[1];
  377. $type = 'Regex matches';
  378. } else {
  379. $tags = preg_quote($tags, '/');
  380. $type = 'Text equals';
  381. }
  382. $regex[] = array(
  383. sprintf('%s "%s"', $type, $tags),
  384. $tags,
  385. $i,
  386. );
  387. continue;
  388. }
  389. foreach ($tags as $tag => $attributes) {
  390. $regex[] = array(
  391. sprintf('Open %s tag', $tag),
  392. sprintf('[\s]*<%s', preg_quote($tag, '/')),
  393. $i,
  394. );
  395. if ($attributes === true) {
  396. $attributes = array();
  397. }
  398. $attrs = array();
  399. $explanations = array();
  400. $i = 1;
  401. foreach ($attributes as $attr => $val) {
  402. if (is_numeric($attr) && preg_match('/^preg\:\/(.+)\/$/i', $val, $matches)) {
  403. $attrs[] = $matches[1];
  404. $explanations[] = sprintf('Regex "%s" matches', $matches[1]);
  405. continue;
  406. } else {
  407. $quotes = '["\']';
  408. if (is_numeric($attr)) {
  409. $attr = $val;
  410. $val = '.+?';
  411. $explanations[] = sprintf('Attribute "%s" present', $attr);
  412. } elseif (!empty($val) && preg_match('/^preg\:\/(.+)\/$/i', $val, $matches)) {
  413. $quotes = '["\']?';
  414. $val = $matches[1];
  415. $explanations[] = sprintf('Attribute "%s" matches "%s"', $attr, $val);
  416. } else {
  417. $explanations[] = sprintf('Attribute "%s" == "%s"', $attr, $val);
  418. $val = preg_quote($val, '/');
  419. }
  420. $attrs[] = '[\s]+' . preg_quote($attr, '/') . '=' . $quotes . $val . $quotes;
  421. }
  422. $i++;
  423. }
  424. if ($attrs) {
  425. $permutations = $this->_arrayPermute($attrs);
  426. $permutationTokens = array();
  427. foreach ($permutations as $permutation) {
  428. $permutationTokens[] = implode('', $permutation);
  429. }
  430. $regex[] = array(
  431. sprintf('%s', implode(', ', $explanations)),
  432. $permutationTokens,
  433. $i,
  434. );
  435. }
  436. $regex[] = array(
  437. sprintf('End %s tag', $tag),
  438. '[\s]*\/?[\s]*>[\n\r]*',
  439. $i,
  440. );
  441. }
  442. }
  443. foreach ($regex as $i => $assertation) {
  444. list($description, $expressions, $itemNum) = $assertation;
  445. $matches = false;
  446. foreach ((array)$expressions as $expression) {
  447. if (preg_match(sprintf('/^%s/s', $expression), $string, $match)) {
  448. $matches = true;
  449. $string = substr($string, strlen($match[0]));
  450. break;
  451. }
  452. }
  453. if (!$matches) {
  454. $this->assertTrue(false, sprintf('Item #%d / regex #%d failed: %s', $itemNum, $i, $description));
  455. if ($fullDebug) {
  456. debug($string, true);
  457. debug($regex, true);
  458. }
  459. return false;
  460. }
  461. }
  462. $this->assertTrue(true, '%s');
  463. return true;
  464. }
  465. /**
  466. * Generates all permutation of an array $items and returns them in a new array.
  467. *
  468. * @param array $items An array of items
  469. * @param array $perms
  470. * @return array
  471. */
  472. protected function _arrayPermute($items, $perms = array()) {
  473. static $permuted;
  474. if (empty($perms)) {
  475. $permuted = array();
  476. }
  477. if (empty($items)) {
  478. $permuted[] = $perms;
  479. } else {
  480. $numItems = count($items) - 1;
  481. for ($i = $numItems; $i >= 0; --$i) {
  482. $newItems = $items;
  483. $newPerms = $perms;
  484. list($tmp) = array_splice($newItems, $i, 1);
  485. array_unshift($newPerms, $tmp);
  486. $this->_arrayPermute($newItems, $newPerms);
  487. }
  488. return $permuted;
  489. }
  490. }
  491. // @codingStandardsIgnoreStart
  492. /**
  493. * Compatibility wrapper function for assertEquals
  494. *
  495. *
  496. * @param mixed $result
  497. * @param mixed $expected
  498. * @param string $message the text to display if the assertion is not correct
  499. * @return void
  500. */
  501. protected static function assertEqual($result, $expected, $message = '') {
  502. return self::assertEquals($expected, $result, $message);
  503. }
  504. /**
  505. * Compatibility wrapper function for assertNotEquals
  506. *
  507. * @param mixed $result
  508. * @param mixed $expected
  509. * @param string $message the text to display if the assertion is not correct
  510. * @return void
  511. */
  512. protected static function assertNotEqual($result, $expected, $message = '') {
  513. return self::assertNotEquals($expected, $result, $message);
  514. }
  515. /**
  516. * Compatibility wrapper function for assertRegexp
  517. *
  518. * @param mixed $pattern a regular expression
  519. * @param string $string the text to be matched
  520. * @param string $message the text to display if the assertion is not correct
  521. * @return void
  522. */
  523. protected static function assertPattern($pattern, $string, $message = '') {
  524. return self::assertRegExp($pattern, $string, $message);
  525. }
  526. /**
  527. * Compatibility wrapper function for assertEquals
  528. *
  529. * @param mixed $actual
  530. * @param mixed $expected
  531. * @param string $message the text to display if the assertion is not correct
  532. * @return void
  533. */
  534. protected static function assertIdentical($actual, $expected, $message = '') {
  535. return self::assertSame($expected, $actual, $message);
  536. }
  537. /**
  538. * Compatibility wrapper function for assertNotEquals
  539. *
  540. * @param mixed $actual
  541. * @param mixed $expected
  542. * @param string $message the text to display if the assertion is not correct
  543. * @return void
  544. */
  545. protected static function assertNotIdentical($actual, $expected, $message = '') {
  546. return self::assertNotSame($expected, $actual, $message);
  547. }
  548. /**
  549. * Compatibility wrapper function for assertNotRegExp
  550. *
  551. * @param mixed $pattern a regular expression
  552. * @param string $string the text to be matched
  553. * @param string $message the text to display if the assertion is not correct
  554. * @return void
  555. */
  556. protected static function assertNoPattern($pattern, $string, $message = '') {
  557. return self::assertNotRegExp($pattern, $string, $message);
  558. }
  559. /**
  560. * assert no errors
  561. */
  562. protected function assertNoErrors() {
  563. }
  564. /**
  565. * Compatibility wrapper function for setExpectedException
  566. *
  567. * @param mixed $expected the name of the Exception or error
  568. * @param string $message the text to display if the assertion is not correct
  569. * @return void
  570. */
  571. protected function expectError($expected = false, $message = '') {
  572. if (!$expected) {
  573. $expected = 'Exception';
  574. }
  575. $this->setExpectedException($expected, $message);
  576. }
  577. /**
  578. * Compatibility wrapper function for setExpectedException
  579. *
  580. * @param mixed $expected the name of the Exception
  581. * @param string $message the text to display if the assertion is not correct
  582. * @return void
  583. */
  584. protected function expectException($name = 'Exception', $message = '') {
  585. $this->setExpectedException($name, $message);
  586. }
  587. /**
  588. * Compatibility wrapper function for assertSame
  589. *
  590. * @param mixed $first
  591. * @param mixed $second
  592. * @param string $message the text to display if the assertion is not correct
  593. * @return void
  594. */
  595. protected static function assertReference(&$first, &$second, $message = '') {
  596. return self::assertSame($first, $second, $message);
  597. }
  598. /**
  599. * Compatibility wrapper for assertIsA
  600. *
  601. * @param string $object
  602. * @param string $type
  603. * @param string $message
  604. * @return void
  605. */
  606. protected static function assertIsA($object, $type, $message = '') {
  607. return self::assertInstanceOf($type, $object, $message);
  608. }
  609. /**
  610. * Compatibility function to test if value is between an acceptable range
  611. *
  612. * @param mixed $result
  613. * @param mixed $expected
  614. * @param mixed $margin the rage of acceptation
  615. * @param string $message the text to display if the assertion is not correct
  616. * @return void
  617. */
  618. protected static function assertWithinMargin($result, $expected, $margin, $message = '') {
  619. $upper = $result + $margin;
  620. $lower = $result - $margin;
  621. return self::assertTrue((($expected <= $upper) && ($expected >= $lower)), $message);
  622. }
  623. /**
  624. * Compatibility function for skipping.
  625. *
  626. * @param boolean $condition Condition to trigger skipping
  627. * @param string $message Message for skip
  628. * @return boolean
  629. */
  630. protected function skipUnless($condition, $message = '') {
  631. if (!$condition) {
  632. $this->markTestSkipped($message);
  633. }
  634. return $condition;
  635. }
  636. // @codingStandardsIgnoreEnd
  637. /**
  638. * Mock a model, maintain fixtures and table association
  639. *
  640. * @param string $model
  641. * @param mixed $methods
  642. * @param array $config
  643. * @throws MissingModelException
  644. * @return Model
  645. */
  646. public function getMockForModel($model, $methods = array(), $config = array()) {
  647. $config += ClassRegistry::config('Model');
  648. list($plugin, $name) = pluginSplit($model, true);
  649. App::uses($name, $plugin . 'Model');
  650. $config = array_merge((array)$config, array('name' => $name));
  651. if (!class_exists($name)) {
  652. throw new MissingModelException(array($model));
  653. }
  654. $mock = $this->getMock($name, $methods, array($config));
  655. ClassRegistry::removeObject($name);
  656. ClassRegistry::addObject($name, $mock);
  657. return $mock;
  658. }
  659. }