1: <?php
2: /**
3: * CakeTestCase 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 1.2.0.4667
16: * @license https://opensource.org/licenses/mit-license.php MIT License
17: */
18:
19: App::uses('CakeFixtureManager', 'TestSuite/Fixture');
20: App::uses('CakeTestFixture', 'TestSuite/Fixture');
21:
22: /**
23: * CakeTestCase class
24: *
25: * @package Cake.TestSuite
26: */
27: abstract class CakeTestCase extends PHPUnit_Framework_TestCase {
28:
29: /**
30: * The class responsible for managing the creation, loading and removing of fixtures
31: *
32: * @var CakeFixtureManager
33: */
34: public $fixtureManager = null;
35:
36: /**
37: * By default, all fixtures attached to this class will be truncated and reloaded after each test.
38: * Set this to false to handle manually
39: *
40: * @var array
41: */
42: public $autoFixtures = true;
43:
44: /**
45: * Control table create/drops on each test method.
46: *
47: * Set this to false to avoid tables to be dropped if they already exist
48: * between each test method. Tables will still be dropped at the
49: * end of each test runner execution.
50: *
51: * @var bool
52: */
53: public $dropTables = true;
54:
55: /**
56: * Configure values to restore at end of test.
57: *
58: * @var array
59: */
60: protected $_configure = array();
61:
62: /**
63: * Path settings to restore at the end of the test.
64: *
65: * @var array
66: */
67: protected $_pathRestore = array();
68:
69: /**
70: * Runs the test case and collects the results in a TestResult object.
71: * If no TestResult object is passed a new one will be created.
72: * This method is run for each test method in this class
73: *
74: * @param PHPUnit_Framework_TestResult $result The test result object
75: * @return PHPUnit_Framework_TestResult
76: * @throws InvalidArgumentException
77: */
78: public function run(PHPUnit_Framework_TestResult $result = null) {
79: $level = ob_get_level();
80:
81: if (!empty($this->fixtureManager)) {
82: $this->fixtureManager->load($this);
83: }
84: $result = parent::run($result);
85: if (!empty($this->fixtureManager)) {
86: $this->fixtureManager->unload($this);
87: unset($this->fixtureManager, $this->db);
88: }
89:
90: for ($i = ob_get_level(); $i < $level; ++$i) {
91: ob_start();
92: }
93:
94: return $result;
95: }
96:
97: /**
98: * Called when a test case method is about to start (to be overridden when needed.)
99: *
100: * @param string $method Test method about to get executed.
101: * @return void
102: */
103: public function startTest($method) {
104: }
105:
106: /**
107: * Called when a test case method has been executed (to be overridden when needed.)
108: *
109: * @param string $method Test method about that was executed.
110: * @return void
111: */
112: public function endTest($method) {
113: }
114:
115: /**
116: * Overrides SimpleTestCase::skipIf to provide a boolean return value
117: *
118: * @param bool $shouldSkip Whether or not the test should be skipped.
119: * @param string $message The message to display.
120: * @return bool
121: */
122: public function skipIf($shouldSkip, $message = '') {
123: if ($shouldSkip) {
124: $this->markTestSkipped($message);
125: }
126: return $shouldSkip;
127: }
128:
129: /**
130: * Setup the test case, backup the static object values so they can be restored.
131: * Specifically backs up the contents of Configure and paths in App if they have
132: * not already been backed up.
133: *
134: * @return void
135: */
136: public function setUp() {
137: parent::setUp();
138:
139: if (empty($this->_configure)) {
140: $this->_configure = Configure::read();
141: }
142: if (empty($this->_pathRestore)) {
143: $this->_pathRestore = App::paths();
144: }
145: if (class_exists('Router', false)) {
146: Router::reload();
147: }
148: }
149:
150: /**
151: * teardown any static object changes and restore them.
152: *
153: * @return void
154: */
155: public function tearDown() {
156: parent::tearDown();
157: App::build($this->_pathRestore, App::RESET);
158: if (class_exists('ClassRegistry', false)) {
159: ClassRegistry::flush();
160: }
161: if (!empty($this->_configure)) {
162: Configure::clear();
163: Configure::write($this->_configure);
164: }
165: if (isset($_GET['debug']) && $_GET['debug']) {
166: ob_flush();
167: }
168: unset($this->_configure, $this->_pathRestore);
169: }
170:
171: /**
172: * See CakeTestSuiteDispatcher::date()
173: *
174: * @param string $format format to be used.
175: * @return string
176: */
177: public static function date($format = 'Y-m-d H:i:s') {
178: return CakeTestSuiteDispatcher::date($format);
179: }
180:
181: // @codingStandardsIgnoreStart PHPUnit overrides don't match CakePHP
182:
183: /**
184: * Announces the start of a test.
185: *
186: * @return void
187: */
188: protected function assertPreConditions() {
189: parent::assertPreConditions();
190: $this->startTest($this->getName());
191: }
192:
193: /**
194: * Announces the end of a test.
195: *
196: * @return void
197: */
198: protected function assertPostConditions() {
199: parent::assertPostConditions();
200: $this->endTest($this->getName());
201: }
202:
203: // @codingStandardsIgnoreEnd
204:
205: /**
206: * Chooses which fixtures to load for a given test
207: *
208: * Each parameter is a model name that corresponds to a fixture, i.e. 'Post', 'Author', etc.
209: *
210: * @return void
211: * @see CakeTestCase::$autoFixtures
212: * @throws Exception when no fixture manager is available.
213: */
214: public function loadFixtures() {
215: if (empty($this->fixtureManager)) {
216: throw new Exception(__d('cake_dev', 'No fixture manager to load the test fixture'));
217: }
218: $args = func_get_args();
219: foreach ($args as $class) {
220: $this->fixtureManager->loadSingle($class, null, $this->dropTables);
221: }
222: }
223:
224: /**
225: * Assert text equality, ignoring differences in newlines.
226: * Helpful for doing cross platform tests of blocks of text.
227: *
228: * @param string $expected The expected value.
229: * @param string $result The actual value.
230: * @param string $message The message to use for failure.
231: * @return bool
232: */
233: public function assertTextNotEquals($expected, $result, $message = '') {
234: $expected = str_replace(array("\r\n", "\r"), "\n", $expected);
235: $result = str_replace(array("\r\n", "\r"), "\n", $result);
236: return $this->assertNotEquals($expected, $result, $message);
237: }
238:
239: /**
240: * Assert text equality, ignoring differences in newlines.
241: * Helpful for doing cross platform tests of blocks of text.
242: *
243: * @param string $expected The expected value.
244: * @param string $result The actual value.
245: * @param string $message message The message to use for failure.
246: * @return bool
247: */
248: public function assertTextEquals($expected, $result, $message = '') {
249: $expected = str_replace(array("\r\n", "\r"), "\n", $expected);
250: $result = str_replace(array("\r\n", "\r"), "\n", $result);
251: return $this->assertEquals($expected, $result, $message);
252: }
253:
254: /**
255: * Asserts that a string starts with a given prefix, ignoring differences in newlines.
256: * Helpful for doing cross platform tests of blocks of text.
257: *
258: * @param string $prefix The prefix to check for.
259: * @param string $string The string to search in.
260: * @param string $message The message to use for failure.
261: * @return bool
262: */
263: public function assertTextStartsWith($prefix, $string, $message = '') {
264: $prefix = str_replace(array("\r\n", "\r"), "\n", $prefix);
265: $string = str_replace(array("\r\n", "\r"), "\n", $string);
266: return $this->assertStringStartsWith($prefix, $string, $message);
267: }
268:
269: /**
270: * Asserts that a string starts not with a given prefix, ignoring differences in newlines.
271: * Helpful for doing cross platform tests of blocks of text.
272: *
273: * @param string $prefix The prefix to not find.
274: * @param string $string The string to search.
275: * @param string $message The message to use for failure.
276: * @return bool
277: */
278: public function assertTextStartsNotWith($prefix, $string, $message = '') {
279: $prefix = str_replace(array("\r\n", "\r"), "\n", $prefix);
280: $string = str_replace(array("\r\n", "\r"), "\n", $string);
281: return $this->assertStringStartsNotWith($prefix, $string, $message);
282: }
283:
284: /**
285: * Asserts that a string ends with a given prefix, ignoring differences in newlines.
286: * Helpful for doing cross platform tests of blocks of text.
287: *
288: * @param string $suffix The suffix to find.
289: * @param string $string The string to search.
290: * @param string $message The message to use for failure.
291: * @return bool
292: */
293: public function assertTextEndsWith($suffix, $string, $message = '') {
294: $suffix = str_replace(array("\r\n", "\r"), "\n", $suffix);
295: $string = str_replace(array("\r\n", "\r"), "\n", $string);
296: return $this->assertStringEndsWith($suffix, $string, $message);
297: }
298:
299: /**
300: * Asserts that a string ends not with a given prefix, ignoring differences in newlines.
301: * Helpful for doing cross platform tests of blocks of text.
302: *
303: * @param string $suffix The suffix to not find.
304: * @param string $string The string to search.
305: * @param string $message The message to use for failure.
306: * @return bool
307: */
308: public function assertTextEndsNotWith($suffix, $string, $message = '') {
309: $suffix = str_replace(array("\r\n", "\r"), "\n", $suffix);
310: $string = str_replace(array("\r\n", "\r"), "\n", $string);
311: return $this->assertStringEndsNotWith($suffix, $string, $message);
312: }
313:
314: /**
315: * Assert that a string contains another string, ignoring differences in newlines.
316: * Helpful for doing cross platform tests of blocks of text.
317: *
318: * @param string $needle The string to search for.
319: * @param string $haystack The string to search through.
320: * @param string $message The message to display on failure.
321: * @param bool $ignoreCase Whether or not the search should be case-sensitive.
322: * @return bool
323: */
324: public function assertTextContains($needle, $haystack, $message = '', $ignoreCase = false) {
325: $needle = str_replace(array("\r\n", "\r"), "\n", $needle);
326: $haystack = str_replace(array("\r\n", "\r"), "\n", $haystack);
327: return $this->assertContains($needle, $haystack, $message, $ignoreCase);
328: }
329:
330: /**
331: * Assert that a text doesn't contain another text, ignoring differences in newlines.
332: * Helpful for doing cross platform tests of blocks of text.
333: *
334: * @param string $needle The string to search for.
335: * @param string $haystack The string to search through.
336: * @param string $message The message to display on failure.
337: * @param bool $ignoreCase Whether or not the search should be case-sensitive.
338: * @return bool
339: */
340: public function assertTextNotContains($needle, $haystack, $message = '', $ignoreCase = false) {
341: $needle = str_replace(array("\r\n", "\r"), "\n", $needle);
342: $haystack = str_replace(array("\r\n", "\r"), "\n", $haystack);
343: return $this->assertNotContains($needle, $haystack, $message, $ignoreCase);
344: }
345:
346: /**
347: * Takes an array $expected and generates a regex from it to match the provided $string.
348: * Samples for $expected:
349: *
350: * Checks for an input tag with a name attribute (contains any non-empty value) and an id
351: * attribute that contains 'my-input':
352: *
353: * ```
354: * array('input' => array('name', 'id' => 'my-input'))
355: * ```
356: *
357: * Checks for two p elements with some text in them:
358: *
359: * ```
360: * array(
361: * array('p' => true),
362: * 'textA',
363: * '/p',
364: * array('p' => true),
365: * 'textB',
366: * '/p'
367: * )
368: * ```
369: *
370: * You can also specify a pattern expression as part of the attribute values, or the tag
371: * being defined, if you prepend the value with preg: and enclose it with slashes, like so:
372: *
373: * ```
374: * array(
375: * array('input' => array('name', 'id' => 'preg:/FieldName\d+/')),
376: * 'preg:/My\s+field/'
377: * )
378: * ```
379: *
380: * Important: This function is very forgiving about whitespace and also accepts any
381: * permutation of attribute order. It will also allow whitespace between specified tags.
382: *
383: * @param string $string An HTML/XHTML/XML string
384: * @param array $expected An array, see above
385: * @param string $fullDebug Whether or not more verbose output should be used.
386: * @return bool
387: */
388: public function assertTags($string, $expected, $fullDebug = false) {
389: $regex = array();
390: $normalized = array();
391: foreach ((array)$expected as $key => $val) {
392: if (!is_numeric($key)) {
393: $normalized[] = array($key => $val);
394: } else {
395: $normalized[] = $val;
396: }
397: }
398: $i = 0;
399: foreach ($normalized as $tags) {
400: if (!is_array($tags)) {
401: $tags = (string)$tags;
402: }
403: $i++;
404: if (is_string($tags) && $tags[0] === '<') {
405: $tags = array(substr($tags, 1) => array());
406: } elseif (is_string($tags)) {
407: $tagsTrimmed = preg_replace('/\s+/m', '', $tags);
408:
409: if (preg_match('/^\*?\//', $tags, $match) && $tagsTrimmed !== '//') {
410: $prefix = array(null, null);
411:
412: if ($match[0] === '*/') {
413: $prefix = array('Anything, ', '.*?');
414: }
415: $regex[] = array(
416: sprintf('%sClose %s tag', $prefix[0], substr($tags, strlen($match[0]))),
417: sprintf('%s<[\s]*\/[\s]*%s[\s]*>[\n\r]*', $prefix[1], substr($tags, strlen($match[0]))),
418: $i,
419: );
420: continue;
421: }
422: if (!empty($tags) && preg_match('/^preg\:\/(.+)\/$/i', $tags, $matches)) {
423: $tags = $matches[1];
424: $type = 'Regex matches';
425: } else {
426: $tags = preg_quote($tags, '/');
427: $type = 'Text equals';
428: }
429: $regex[] = array(
430: sprintf('%s "%s"', $type, $tags),
431: $tags,
432: $i,
433: );
434: continue;
435: }
436: foreach ($tags as $tag => $attributes) {
437: $regex[] = array(
438: sprintf('Open %s tag', $tag),
439: sprintf('[\s]*<%s', preg_quote($tag, '/')),
440: $i,
441: );
442: if ($attributes === true) {
443: $attributes = array();
444: }
445: $attrs = array();
446: $explanations = array();
447: $i = 1;
448: foreach ($attributes as $attr => $val) {
449: if (is_numeric($attr) && preg_match('/^preg\:\/(.+)\/$/i', $val, $matches)) {
450: $attrs[] = $matches[1];
451: $explanations[] = sprintf('Regex "%s" matches', $matches[1]);
452: continue;
453: } else {
454: $quotes = '["\']';
455: if (is_numeric($attr)) {
456: $attr = $val;
457: $val = '.+?';
458: $explanations[] = sprintf('Attribute "%s" present', $attr);
459: } elseif (!empty($val) && preg_match('/^preg\:\/(.+)\/$/i', $val, $matches)) {
460: $val = str_replace(
461: array('.*', '.+'),
462: array('.*?', '.+?'),
463: $matches[1]
464: );
465: $quotes = $val !== $matches[1] ? '["\']' : '["\']?';
466:
467: $explanations[] = sprintf('Attribute "%s" matches "%s"', $attr, $val);
468: } else {
469: $explanations[] = sprintf('Attribute "%s" == "%s"', $attr, $val);
470: $val = preg_quote($val, '/');
471: }
472: $attrs[] = '[\s]+' . preg_quote($attr, '/') . '=' . $quotes . $val . $quotes;
473: }
474: $i++;
475: }
476: if ($attrs) {
477: $regex[] = array(
478: 'explains' => $explanations,
479: 'attrs' => $attrs,
480: );
481: }
482: $regex[] = array(
483: sprintf('End %s tag', $tag),
484: '[\s]*\/?[\s]*>[\n\r]*',
485: $i,
486: );
487: }
488: }
489: foreach ($regex as $i => $assertion) {
490: $matches = false;
491: if (isset($assertion['attrs'])) {
492: $string = $this->_assertAttributes($assertion, $string);
493: continue;
494: }
495:
496: list($description, $expressions, $itemNum) = $assertion;
497: foreach ((array)$expressions as $expression) {
498: if (preg_match(sprintf('/^%s/s', $expression), $string, $match)) {
499: $matches = true;
500: $string = substr($string, strlen($match[0]));
501: break;
502: }
503: }
504: if (!$matches) {
505: $this->assertTrue(false, sprintf('Item #%d / regex #%d failed: %s', $itemNum, $i, $description));
506: if ($fullDebug) {
507: debug($string, true);
508: debug($regex, true);
509: }
510: return false;
511: }
512: }
513:
514: $this->assertTrue(true, '%s');
515: return true;
516: }
517:
518: /**
519: * Check the attributes as part of an assertTags() check.
520: *
521: * @param array $assertions Assertions to run.
522: * @param string $string The HTML string to check.
523: * @return void
524: */
525: protected function _assertAttributes($assertions, $string) {
526: $asserts = $assertions['attrs'];
527: $explains = $assertions['explains'];
528: $len = count($asserts);
529: do {
530: $matches = false;
531: foreach ($asserts as $j => $assert) {
532: if (preg_match(sprintf('/^%s/s', $assert), $string, $match)) {
533: $matches = true;
534: $string = substr($string, strlen($match[0]));
535: array_splice($asserts, $j, 1);
536: array_splice($explains, $j, 1);
537: break;
538: }
539: }
540: if ($matches === false) {
541: $this->assertTrue(false, 'Attribute did not match. Was expecting ' . $explains[$j]);
542: }
543: $len = count($asserts);
544: } while ($len > 0);
545: return $string;
546: }
547:
548: // @codingStandardsIgnoreStart
549:
550: /**
551: * Compatibility wrapper function for assertEquals
552: *
553: * @param mixed $result
554: * @param mixed $expected
555: * @param string $message the text to display if the assertion is not correct
556: * @deprecated 3.0.0 This is a compatibility wrapper for 1.x. It will be removed in 3.0
557: * @return void
558: */
559: protected static function assertEqual($result, $expected, $message = '') {
560: return static::assertEquals($expected, $result, $message);
561: }
562:
563: /**
564: * Compatibility wrapper function for assertNotEquals
565: *
566: * @param mixed $result
567: * @param mixed $expected
568: * @param string $message the text to display if the assertion is not correct
569: * @deprecated 3.0.0 This is a compatibility wrapper for 1.x. It will be removed in 3.0
570: * @return void
571: */
572: protected static function assertNotEqual($result, $expected, $message = '') {
573: return static::assertNotEquals($expected, $result, $message);
574: }
575:
576: /**
577: * Compatibility wrapper function for assertRegexp
578: *
579: * @param mixed $pattern a regular expression
580: * @param string $string the text to be matched
581: * @param string $message the text to display if the assertion is not correct
582: * @deprecated 3.0.0 This is a compatibility wrapper for 1.x. It will be removed in 3.0
583: * @return void
584: */
585: protected static function assertPattern($pattern, $string, $message = '') {
586: return static::assertRegExp($pattern, $string, $message);
587: }
588:
589: /**
590: * Compatibility wrapper function for assertEquals
591: *
592: * @param mixed $actual
593: * @param mixed $expected
594: * @param string $message the text to display if the assertion is not correct
595: * @deprecated 3.0.0 This is a compatibility wrapper for 1.x. It will be removed in 3.0
596: * @return void
597: */
598: protected static function assertIdentical($actual, $expected, $message = '') {
599: return static::assertSame($expected, $actual, $message);
600: }
601:
602: /**
603: * Compatibility wrapper function for assertNotEquals
604: *
605: * @param mixed $actual
606: * @param mixed $expected
607: * @param string $message the text to display if the assertion is not correct
608: * @deprecated 3.0.0 This is a compatibility wrapper for 1.x. It will be removed in 3.0
609: * @return void
610: */
611: protected static function assertNotIdentical($actual, $expected, $message = '') {
612: return static::assertNotSame($expected, $actual, $message);
613: }
614:
615: /**
616: * Compatibility wrapper function for assertNotRegExp
617: *
618: * @param mixed $pattern a regular expression
619: * @param string $string the text to be matched
620: * @param string $message the text to display if the assertion is not correct
621: * @deprecated 3.0.0 This is a compatibility wrapper for 1.x. It will be removed in 3.0
622: * @return void
623: */
624: protected static function assertNoPattern($pattern, $string, $message = '') {
625: return static::assertNotRegExp($pattern, $string, $message);
626: }
627:
628: /**
629: * assert no errors
630: *
631: * @deprecated 3.0.0 This is a compatibility wrapper for 1.x. It will be removed in 3.0
632: * @return void
633: */
634: protected function assertNoErrors() {
635: }
636:
637: /**
638: * Compatibility wrapper function for setExpectedException
639: *
640: * @param mixed $expected the name of the Exception or error
641: * @param string $message the text to display if the assertion is not correct
642: * @deprecated 3.0.0 This is a compatibility wrapper for 1.x. It will be removed in 3.0
643: * @return void
644: */
645: protected function expectError($expected = false, $message = '') {
646: if (!$expected) {
647: $expected = 'Exception';
648: }
649: $this->setExpectedException($expected, $message);
650: }
651:
652: /**
653: * Compatibility wrapper function for setExpectedException
654: *
655: * @param mixed $name The name of the expected Exception.
656: * @param string $message the text to display if the assertion is not correct
657: * @deprecated 3.0.0 This is a compatibility wrapper for 1.x. It will be removed in 3.0.
658: * @return void
659: */
660: public function expectException($name = 'Exception', $message = '') {
661: $this->setExpectedException($name, $message);
662: }
663:
664: /**
665: * Compatibility wrapper function for assertSame
666: *
667: * @param mixed $first
668: * @param mixed $second
669: * @param string $message the text to display if the assertion is not correct
670: * @deprecated 3.0.0 This is a compatibility wrapper for 1.x. It will be removed in 3.0
671: * @return void
672: */
673: protected static function assertReference(&$first, &$second, $message = '') {
674: return static::assertSame($first, $second, $message);
675: }
676:
677: /**
678: * Compatibility wrapper for assertIsA
679: *
680: * @param string $object
681: * @param string $type
682: * @param string $message
683: * @deprecated 3.0.0 This is a compatibility wrapper for 1.x. It will be removed in 3.0
684: * @return void
685: */
686: protected static function assertIsA($object, $type, $message = '') {
687: return static::assertInstanceOf($type, $object, $message);
688: }
689:
690: /**
691: * Compatibility function to test if value is between an acceptable range
692: *
693: * @param mixed $result
694: * @param mixed $expected
695: * @param mixed $margin the rage of acceptation
696: * @param string $message the text to display if the assertion is not correct
697: * @return void
698: */
699: protected static function assertWithinMargin($result, $expected, $margin, $message = '') {
700: $upper = $result + $margin;
701: $lower = $result - $margin;
702: return static::assertTrue((($expected <= $upper) && ($expected >= $lower)), $message);
703: }
704:
705: /**
706: * Compatibility function for skipping.
707: *
708: * @param bool $condition Condition to trigger skipping
709: * @param string $message Message for skip
710: * @return bool
711: */
712: protected function skipUnless($condition, $message = '') {
713: if (!$condition) {
714: $this->markTestSkipped($message);
715: }
716: return $condition;
717: }
718: // @codingStandardsIgnoreEnd
719:
720: /**
721: * Returns a mock object for the specified class.
722: *
723: * @param string $originalClassName The class name of the object to be mocked.
724: * @param array $methods By default, all methods of the given class are replaced
725: * with a test double that just returns NULL unless a return value is configured
726: * using will($this->returnValue()), for instance.
727: * When the second (optional) parameter is provided, only the methods whose names
728: * are in the array are replaced with a configurable test double. The behavior
729: * of the other methods is not changed. Providing NULL as the parameter means
730: * that no methods will be replaced.
731: * @param array $arguments The third (optional) parameter may hold a parameter
732: * array that is passed to the original class' constructor (which is not replaced
733: * with a dummy implementation by default).
734: * @param string $mockClassName The fourth (optional) parameter can be used to
735: * specify a class name for the generated test double class.
736: * @param bool $callOriginalConstructor The fifth (optional) parameter can be
737: * used to disable the call to the original class' constructor.
738: * @param bool $callOriginalClone The sixth (optional) parameter can be used
739: * to disable the call to the original class' clone constructor.
740: * @param bool $callAutoload The seventh (optional) parameter can be used to
741: * disable __autoload() during the generation of the test double class.
742: * @return object
743: * @deprecated Use `getMockBuilder()` or `createMock()` in new unit tests.
744: * @see https://phpunit.de/manual/current/en/test-doubles.html
745: */
746: protected function _buildMock(
747: $originalClassName,
748: $methods = array(),
749: array $arguments = array(),
750: $mockClassName = '',
751: $callOriginalConstructor = true,
752: $callOriginalClone = true,
753: $callAutoload = true
754: ) {
755: $MockBuilder = $this->getMockBuilder($originalClassName);
756: if (!empty($methods)) {
757: $MockBuilder = $MockBuilder->setMethods($methods);
758: }
759: if (!empty($arguments)) {
760: $MockBuilder = $MockBuilder->setConstructorArgs($arguments);
761: }
762: if ($mockClassName != '') {
763: $MockBuilder = $MockBuilder->setMockClassName($mockClassName);
764: }
765: if ($callOriginalConstructor !== true) {
766: $MockBuilder = $MockBuilder->disableOriginalConstructor();
767: }
768: if ($callOriginalClone !== true) {
769: $MockBuilder = $MockBuilder->disableOriginalClone();
770: }
771: if ($callAutoload !== true) {
772: $MockBuilder = $MockBuilder->disableAutoload();
773: }
774: return $MockBuilder->getMock();
775: }
776:
777: /**
778: * Returns a mock object for the specified class.
779: *
780: * @param string $originalClassName The class name of the object to be mocked.
781: * @param array $methods By default, all methods of the given class are replaced
782: * with a test double that just returns NULL unless a return value is configured
783: * using will($this->returnValue()), for instance.
784: * When the second (optional) parameter is provided, only the methods whose names
785: * are in the array are replaced with a configurable test double. The behavior
786: * of the other methods is not changed. Providing NULL as the parameter means
787: * that no methods will be replaced.
788: * @param array $arguments The third (optional) parameter may hold a parameter
789: * array that is passed to the original class' constructor (which is not replaced
790: * with a dummy implementation by default).
791: * @param string $mockClassName The fourth (optional) parameter can be used to
792: * specify a class name for the generated test double class.
793: * @param bool $callOriginalConstructor The fifth (optional) parameter can be
794: * used to disable the call to the original class' constructor.
795: * @param bool $callOriginalClone The sixth (optional) parameter can be used
796: * to disable the call to the original class' clone constructor.
797: * @param bool $callAutoload The seventh (optional) parameter can be used to
798: * disable __autoload() during the generation of the test double class.
799: * @param bool $cloneArguments Not supported.
800: * @param bool $callOriginalMethods Not supported.
801: * @param string $proxyTarget Not supported.
802: * @return object
803: * @throws InvalidArgumentException When not supported parameters are set.
804: * @deprecated Use `getMockBuilder()` or `createMock()` in new unit tests.
805: * @see https://phpunit.de/manual/current/en/test-doubles.html
806: */
807: public function getMock(
808: $originalClassName,
809: $methods = array(),
810: array $arguments = array(),
811: $mockClassName = '',
812: $callOriginalConstructor = true,
813: $callOriginalClone = true,
814: $callAutoload = true,
815: $cloneArguments = false,
816: $callOriginalMethods = false,
817: $proxyTarget = null
818: ) {
819: $phpUnitVersion = PHPUnit_Runner_Version::id();
820: if (version_compare($phpUnitVersion, '5.7.0', '<')) {
821: return parent::getMock($originalClassName, $methods, $arguments,
822: $mockClassName, $callOriginalConstructor, $callOriginalClone,
823: $callAutoload, $cloneArguments, $callOriginalMethods, $proxyTarget);
824: }
825: if ($cloneArguments) {
826: throw new InvalidArgumentException('$cloneArguments parameter is not supported');
827: }
828: if ($callOriginalMethods) {
829: throw new InvalidArgumentException('$callOriginalMethods parameter is not supported');
830: }
831: if ($proxyTarget !== null) {
832: throw new InvalidArgumentException('$proxyTarget parameter is not supported');
833: }
834: return $this->_buildMock(
835: $originalClassName,
836: $methods,
837: $arguments,
838: $mockClassName,
839: $callOriginalConstructor,
840: $callOriginalClone,
841: $callAutoload
842: );
843: }
844:
845: /**
846: * Mock a model, maintain fixtures and table association
847: *
848: * @param string $model The model to get a mock for.
849: * @param mixed $methods The list of methods to mock
850: * @param array $config The config data for the mock's constructor.
851: * @throws MissingModelException
852: * @return Model
853: */
854: public function getMockForModel($model, $methods = array(), $config = array()) {
855: $defaults = ClassRegistry::config('Model');
856: unset($defaults['ds']);
857:
858: list($plugin, $name) = pluginSplit($model, true);
859: App::uses($name, $plugin . 'Model');
860:
861: $config = array_merge($defaults, (array)$config, array('name' => $name));
862:
863: if (!class_exists($name)) {
864: throw new MissingModelException(array($model));
865: }
866: $mock = $this->getMock($name, $methods, array($config));
867:
868: $availableDs = array_keys(ConnectionManager::enumConnectionObjects());
869:
870: if ($mock->useDbConfig !== 'test' && in_array('test_' . $mock->useDbConfig, $availableDs)) {
871: $mock->useDbConfig = 'test_' . $mock->useDbConfig;
872: $mock->setDataSource($mock->useDbConfig);
873: } else {
874: $mock->useDbConfig = 'test';
875: $mock->setDataSource('test');
876: }
877:
878: ClassRegistry::removeObject($name);
879: ClassRegistry::addObject($name, $mock);
880: return $mock;
881: }
882:
883: }
884: