PageRenderTime 49ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/simpletest/test/mock_objects_test.php

https://github.com/3scale/3scale_ws_api_for_php
PHP | 985 lines | 854 code | 129 blank | 2 comment | 1 complexity | ac349818b93e7658dee4e45f713298e3 MD5 | raw file
Possible License(s): MIT, LGPL-2.1
  1. <?php
  2. // $Id: mock_objects_test.php 1900 2009-07-29 11:44:37Z lastcraft $
  3. require_once(dirname(__FILE__) . '/../autorun.php');
  4. require_once(dirname(__FILE__) . '/../expectation.php');
  5. require_once(dirname(__FILE__) . '/../mock_objects.php');
  6. class TestOfAnythingExpectation extends UnitTestCase {
  7. function testSimpleInteger() {
  8. $expectation = new AnythingExpectation();
  9. $this->assertTrue($expectation->test(33));
  10. $this->assertTrue($expectation->test(false));
  11. $this->assertTrue($expectation->test(null));
  12. }
  13. }
  14. class TestOfParametersExpectation extends UnitTestCase {
  15. function testEmptyMatch() {
  16. $expectation = new ParametersExpectation(array());
  17. $this->assertTrue($expectation->test(array()));
  18. $this->assertFalse($expectation->test(array(33)));
  19. }
  20. function testSingleMatch() {
  21. $expectation = new ParametersExpectation(array(0));
  22. $this->assertFalse($expectation->test(array(1)));
  23. $this->assertTrue($expectation->test(array(0)));
  24. }
  25. function testAnyMatch() {
  26. $expectation = new ParametersExpectation(false);
  27. $this->assertTrue($expectation->test(array()));
  28. $this->assertTrue($expectation->test(array(1, 2)));
  29. }
  30. function testMissingParameter() {
  31. $expectation = new ParametersExpectation(array(0));
  32. $this->assertFalse($expectation->test(array()));
  33. }
  34. function testNullParameter() {
  35. $expectation = new ParametersExpectation(array(null));
  36. $this->assertTrue($expectation->test(array(null)));
  37. $this->assertFalse($expectation->test(array()));
  38. }
  39. function testAnythingExpectations() {
  40. $expectation = new ParametersExpectation(array(new AnythingExpectation()));
  41. $this->assertFalse($expectation->test(array()));
  42. $this->assertIdentical($expectation->test(array(null)), true);
  43. $this->assertIdentical($expectation->test(array(13)), true);
  44. }
  45. function testOtherExpectations() {
  46. $expectation = new ParametersExpectation(
  47. array(new PatternExpectation('/hello/i')));
  48. $this->assertFalse($expectation->test(array('Goodbye')));
  49. $this->assertTrue($expectation->test(array('hello')));
  50. $this->assertTrue($expectation->test(array('Hello')));
  51. }
  52. function testIdentityOnly() {
  53. $expectation = new ParametersExpectation(array("0"));
  54. $this->assertFalse($expectation->test(array(0)));
  55. $this->assertTrue($expectation->test(array("0")));
  56. }
  57. function testLongList() {
  58. $expectation = new ParametersExpectation(
  59. array("0", 0, new AnythingExpectation(), false));
  60. $this->assertTrue($expectation->test(array("0", 0, 37, false)));
  61. $this->assertFalse($expectation->test(array("0", 0, 37, true)));
  62. $this->assertFalse($expectation->test(array("0", 0, 37)));
  63. }
  64. }
  65. class TestOfSimpleSignatureMap extends UnitTestCase {
  66. function testEmpty() {
  67. $map = new SimpleSignatureMap();
  68. $this->assertFalse($map->isMatch("any", array()));
  69. $this->assertNull($map->findFirstAction("any", array()));
  70. }
  71. function testDifferentCallSignaturesCanHaveDifferentReferences() {
  72. $map = new SimpleSignatureMap();
  73. $fred = 'Fred';
  74. $jim = 'jim';
  75. $map->add(array(0), $fred);
  76. $map->add(array('0'), $jim);
  77. $this->assertSame($fred, $map->findFirstAction(array(0)));
  78. $this->assertSame($jim, $map->findFirstAction(array('0')));
  79. }
  80. function testWildcard() {
  81. $fred = 'Fred';
  82. $map = new SimpleSignatureMap();
  83. $map->add(array(new AnythingExpectation(), 1, 3), $fred);
  84. $this->assertTrue($map->isMatch(array(2, 1, 3)));
  85. $this->assertSame($map->findFirstAction(array(2, 1, 3)), $fred);
  86. }
  87. function testAllWildcard() {
  88. $fred = 'Fred';
  89. $map = new SimpleSignatureMap();
  90. $this->assertFalse($map->isMatch(array(2, 1, 3)));
  91. $map->add('', $fred);
  92. $this->assertTrue($map->isMatch(array(2, 1, 3)));
  93. $this->assertSame($map->findFirstAction(array(2, 1, 3)), $fred);
  94. }
  95. function testOrdering() {
  96. $map = new SimpleSignatureMap();
  97. $map->add(array(1, 2), new SimpleByValue("1, 2"));
  98. $map->add(array(1, 3), new SimpleByValue("1, 3"));
  99. $map->add(array(1), new SimpleByValue("1"));
  100. $map->add(array(1, 4), new SimpleByValue("1, 4"));
  101. $map->add(array(new AnythingExpectation()), new SimpleByValue("Any"));
  102. $map->add(array(2), new SimpleByValue("2"));
  103. $map->add("", new SimpleByValue("Default"));
  104. $map->add(array(), new SimpleByValue("None"));
  105. $this->assertEqual($map->findFirstAction(array(1, 2)), new SimpleByValue("1, 2"));
  106. $this->assertEqual($map->findFirstAction(array(1, 3)), new SimpleByValue("1, 3"));
  107. $this->assertEqual($map->findFirstAction(array(1, 4)), new SimpleByValue("1, 4"));
  108. $this->assertEqual($map->findFirstAction(array(1)), new SimpleByValue("1"));
  109. $this->assertEqual($map->findFirstAction(array(2)), new SimpleByValue("Any"));
  110. $this->assertEqual($map->findFirstAction(array(3)), new SimpleByValue("Any"));
  111. $this->assertEqual($map->findFirstAction(array()), new SimpleByValue("Default"));
  112. }
  113. }
  114. class TestOfCallSchedule extends UnitTestCase {
  115. function testCanBeSetToAlwaysReturnTheSameReference() {
  116. $a = 5;
  117. $schedule = new SimpleCallSchedule();
  118. $schedule->register('aMethod', false, new SimpleByReference($a));
  119. $this->assertReference($schedule->respond(0, 'aMethod', array()), $a);
  120. $this->assertReference($schedule->respond(1, 'aMethod', array()), $a);
  121. }
  122. function testSpecificSignaturesOverrideTheAlwaysCase() {
  123. $any = 'any';
  124. $one = 'two';
  125. $schedule = new SimpleCallSchedule();
  126. $schedule->register('aMethod', array(1), new SimpleByReference($one));
  127. $schedule->register('aMethod', false, new SimpleByReference($any));
  128. $this->assertReference($schedule->respond(0, 'aMethod', array(2)), $any);
  129. $this->assertReference($schedule->respond(0, 'aMethod', array(1)), $one);
  130. }
  131. function testReturnsCanBeSetOverTime() {
  132. $one = 'one';
  133. $two = 'two';
  134. $schedule = new SimpleCallSchedule();
  135. $schedule->registerAt(0, 'aMethod', false, new SimpleByReference($one));
  136. $schedule->registerAt(1, 'aMethod', false, new SimpleByReference($two));
  137. $this->assertReference($schedule->respond(0, 'aMethod', array()), $one);
  138. $this->assertReference($schedule->respond(1, 'aMethod', array()), $two);
  139. }
  140. function testReturnsOverTimecanBeAlteredByTheArguments() {
  141. $one = '1';
  142. $two = '2';
  143. $two_a = '2a';
  144. $schedule = new SimpleCallSchedule();
  145. $schedule->registerAt(0, 'aMethod', false, new SimpleByReference($one));
  146. $schedule->registerAt(1, 'aMethod', array('a'), new SimpleByReference($two_a));
  147. $schedule->registerAt(1, 'aMethod', false, new SimpleByReference($two));
  148. $this->assertReference($schedule->respond(0, 'aMethod', array()), $one);
  149. $this->assertReference($schedule->respond(1, 'aMethod', array()), $two);
  150. $this->assertReference($schedule->respond(1, 'aMethod', array('a')), $two_a);
  151. }
  152. function testCanReturnByValue() {
  153. $a = 5;
  154. $schedule = new SimpleCallSchedule();
  155. $schedule->register('aMethod', false, new SimpleByValue($a));
  156. $this->assertCopy($schedule->respond(0, 'aMethod', array()), $a);
  157. }
  158. function testCanThrowException() {
  159. if (version_compare(phpversion(), '5', '>=')) {
  160. $schedule = new SimpleCallSchedule();
  161. $schedule->register('aMethod', false, new SimpleThrower(new Exception('Ouch')));
  162. $this->expectException(new Exception('Ouch'));
  163. $schedule->respond(0, 'aMethod', array());
  164. }
  165. }
  166. function testCanEmitError() {
  167. $schedule = new SimpleCallSchedule();
  168. $schedule->register('aMethod', false, new SimpleErrorThrower('Ouch', E_USER_WARNING));
  169. $this->expectError('Ouch');
  170. $schedule->respond(0, 'aMethod', array());
  171. }
  172. }
  173. class Dummy {
  174. function Dummy() {
  175. }
  176. function aMethod() {
  177. return true;
  178. }
  179. function &aReferenceMethod() {
  180. return true;
  181. }
  182. function anotherMethod() {
  183. return true;
  184. }
  185. }
  186. Mock::generate('Dummy');
  187. Mock::generate('Dummy', 'AnotherMockDummy');
  188. Mock::generate('Dummy', 'MockDummyWithExtraMethods', array('extraMethod'));
  189. class TestOfMockGeneration extends UnitTestCase {
  190. function testCloning() {
  191. $mock = new MockDummy();
  192. $this->assertTrue(method_exists($mock, "aMethod"));
  193. $this->assertNull($mock->aMethod());
  194. }
  195. function testCloningWithExtraMethod() {
  196. $mock = new MockDummyWithExtraMethods();
  197. $this->assertTrue(method_exists($mock, "extraMethod"));
  198. }
  199. function testCloningWithChosenClassName() {
  200. $mock = new AnotherMockDummy();
  201. $this->assertTrue(method_exists($mock, "aMethod"));
  202. }
  203. }
  204. class TestOfMockReturns extends UnitTestCase {
  205. function testDefaultReturn() {
  206. $mock = new MockDummy();
  207. $mock->returnsByValue("aMethod", "aaa");
  208. $this->assertIdentical($mock->aMethod(), "aaa");
  209. $this->assertIdentical($mock->aMethod(), "aaa");
  210. }
  211. function testParameteredReturn() {
  212. $mock = new MockDummy();
  213. $mock->returnsByValue('aMethod', 'aaa', array(1, 2, 3));
  214. $this->assertNull($mock->aMethod());
  215. $this->assertIdentical($mock->aMethod(1, 2, 3), 'aaa');
  216. }
  217. function testSetReturnGivesObjectReference() {
  218. $mock = new MockDummy();
  219. $object = new Dummy();
  220. $mock->returns('aMethod', $object, array(1, 2, 3));
  221. $this->assertSame($mock->aMethod(1, 2, 3), $object);
  222. }
  223. function testSetReturnReferenceGivesOriginalReference() {
  224. $mock = new MockDummy();
  225. $object = 1;
  226. $mock->returnsByReference('aReferenceMethod', $object, array(1, 2, 3));
  227. $this->assertReference($mock->aReferenceMethod(1, 2, 3), $object);
  228. }
  229. function testReturnValueCanBeChosenJustByPatternMatchingArguments() {
  230. $mock = new MockDummy();
  231. $mock->returnsByValue(
  232. "aMethod",
  233. "aaa",
  234. array(new PatternExpectation('/hello/i')));
  235. $this->assertIdentical($mock->aMethod('Hello'), 'aaa');
  236. $this->assertNull($mock->aMethod('Goodbye'));
  237. }
  238. function testMultipleMethods() {
  239. $mock = new MockDummy();
  240. $mock->returnsByValue("aMethod", 100, array(1));
  241. $mock->returnsByValue("aMethod", 200, array(2));
  242. $mock->returnsByValue("anotherMethod", 10, array(1));
  243. $mock->returnsByValue("anotherMethod", 20, array(2));
  244. $this->assertIdentical($mock->aMethod(1), 100);
  245. $this->assertIdentical($mock->anotherMethod(1), 10);
  246. $this->assertIdentical($mock->aMethod(2), 200);
  247. $this->assertIdentical($mock->anotherMethod(2), 20);
  248. }
  249. function testReturnSequence() {
  250. $mock = new MockDummy();
  251. $mock->returnsByValueAt(0, "aMethod", "aaa");
  252. $mock->returnsByValueAt(1, "aMethod", "bbb");
  253. $mock->returnsByValueAt(3, "aMethod", "ddd");
  254. $this->assertIdentical($mock->aMethod(), "aaa");
  255. $this->assertIdentical($mock->aMethod(), "bbb");
  256. $this->assertNull($mock->aMethod());
  257. $this->assertIdentical($mock->aMethod(), "ddd");
  258. }
  259. function testSetReturnReferenceAtGivesOriginal() {
  260. $mock = new MockDummy();
  261. $object = 100;
  262. $mock->returnsByReferenceAt(1, "aReferenceMethod", $object);
  263. $this->assertNull($mock->aReferenceMethod());
  264. $this->assertReference($mock->aReferenceMethod(), $object);
  265. $this->assertNull($mock->aReferenceMethod());
  266. }
  267. function testReturnsAtGivesOriginalObjectHandle() {
  268. $mock = new MockDummy();
  269. $object = new Dummy();
  270. $mock->returnsAt(1, "aMethod", $object);
  271. $this->assertNull($mock->aMethod());
  272. $this->assertSame($mock->aMethod(), $object);
  273. $this->assertNull($mock->aMethod());
  274. }
  275. function testComplicatedReturnSequence() {
  276. $mock = new MockDummy();
  277. $object = new Dummy();
  278. $mock->returnsAt(1, "aMethod", "aaa", array("a"));
  279. $mock->returnsAt(1, "aMethod", "bbb");
  280. $mock->returnsAt(2, "aMethod", $object, array('*', 2));
  281. $mock->returnsAt(2, "aMethod", "value", array('*', 3));
  282. $mock->returns("aMethod", 3, array(3));
  283. $this->assertNull($mock->aMethod());
  284. $this->assertEqual($mock->aMethod("a"), "aaa");
  285. $this->assertSame($mock->aMethod(1, 2), $object);
  286. $this->assertEqual($mock->aMethod(3), 3);
  287. $this->assertNull($mock->aMethod());
  288. }
  289. function testMultipleMethodSequences() {
  290. $mock = new MockDummy();
  291. $mock->returnsByValueAt(0, "aMethod", "aaa");
  292. $mock->returnsByValueAt(1, "aMethod", "bbb");
  293. $mock->returnsByValueAt(0, "anotherMethod", "ccc");
  294. $mock->returnsByValueAt(1, "anotherMethod", "ddd");
  295. $this->assertIdentical($mock->aMethod(), "aaa");
  296. $this->assertIdentical($mock->anotherMethod(), "ccc");
  297. $this->assertIdentical($mock->aMethod(), "bbb");
  298. $this->assertIdentical($mock->anotherMethod(), "ddd");
  299. }
  300. function testSequenceFallback() {
  301. $mock = new MockDummy();
  302. $mock->returnsByValueAt(0, "aMethod", "aaa", array('a'));
  303. $mock->returnsByValueAt(1, "aMethod", "bbb", array('a'));
  304. $mock->returnsByValue("aMethod", "AAA");
  305. $this->assertIdentical($mock->aMethod('a'), "aaa");
  306. $this->assertIdentical($mock->aMethod('b'), "AAA");
  307. }
  308. function testMethodInterference() {
  309. $mock = new MockDummy();
  310. $mock->returnsByValueAt(0, "anotherMethod", "aaa");
  311. $mock->returnsByValue("aMethod", "AAA");
  312. $this->assertIdentical($mock->aMethod(), "AAA");
  313. $this->assertIdentical($mock->anotherMethod(), "aaa");
  314. }
  315. }
  316. class TestOfMockExpectationsThatPass extends UnitTestCase {
  317. function testAnyArgument() {
  318. $mock = new MockDummy();
  319. $mock->expect('aMethod', array('*'));
  320. $mock->aMethod(1);
  321. $mock->aMethod('hello');
  322. }
  323. function testAnyTwoArguments() {
  324. $mock = new MockDummy();
  325. $mock->expect('aMethod', array('*', '*'));
  326. $mock->aMethod(1, 2);
  327. }
  328. function testSpecificArgument() {
  329. $mock = new MockDummy();
  330. $mock->expect('aMethod', array(1));
  331. $mock->aMethod(1);
  332. }
  333. function testExpectation() {
  334. $mock = new MockDummy();
  335. $mock->expect('aMethod', array(new IsAExpectation('Dummy')));
  336. $mock->aMethod(new Dummy());
  337. }
  338. function testArgumentsInSequence() {
  339. $mock = new MockDummy();
  340. $mock->expectAt(0, 'aMethod', array(1, 2));
  341. $mock->expectAt(1, 'aMethod', array(3, 4));
  342. $mock->aMethod(1, 2);
  343. $mock->aMethod(3, 4);
  344. }
  345. function testAtLeastOnceSatisfiedByOneCall() {
  346. $mock = new MockDummy();
  347. $mock->expectAtLeastOnce('aMethod');
  348. $mock->aMethod();
  349. }
  350. function testAtLeastOnceSatisfiedByTwoCalls() {
  351. $mock = new MockDummy();
  352. $mock->expectAtLeastOnce('aMethod');
  353. $mock->aMethod();
  354. $mock->aMethod();
  355. }
  356. function testOnceSatisfiedByOneCall() {
  357. $mock = new MockDummy();
  358. $mock->expectOnce('aMethod');
  359. $mock->aMethod();
  360. }
  361. function testMinimumCallsSatisfiedByEnoughCalls() {
  362. $mock = new MockDummy();
  363. $mock->expectMinimumCallCount('aMethod', 1);
  364. $mock->aMethod();
  365. }
  366. function testMinimumCallsSatisfiedByTooManyCalls() {
  367. $mock = new MockDummy();
  368. $mock->expectMinimumCallCount('aMethod', 3);
  369. $mock->aMethod();
  370. $mock->aMethod();
  371. $mock->aMethod();
  372. $mock->aMethod();
  373. }
  374. function testMaximumCallsSatisfiedByEnoughCalls() {
  375. $mock = new MockDummy();
  376. $mock->expectMaximumCallCount('aMethod', 1);
  377. $mock->aMethod();
  378. }
  379. function testMaximumCallsSatisfiedByNoCalls() {
  380. $mock = new MockDummy();
  381. $mock->expectMaximumCallCount('aMethod', 1);
  382. }
  383. }
  384. class MockWithInjectedTestCase extends SimpleMock {
  385. protected function getCurrentTestCase() {
  386. return SimpleTest::getContext()->getTest()->getMockedTest();
  387. }
  388. }
  389. SimpleTest::setMockBaseClass('MockWithInjectedTestCase');
  390. Mock::generate('Dummy', 'MockDummyWithInjectedTestCase');
  391. SimpleTest::setMockBaseClass('SimpleMock');
  392. Mock::generate('SimpleTestCase');
  393. class LikeExpectation extends IdenticalExpectation {
  394. function __construct($expectation) {
  395. $expectation->message = '';
  396. parent::__construct($expectation);
  397. }
  398. function test($compare) {
  399. $compare->message = '';
  400. return parent::test($compare);
  401. }
  402. function testMessage($compare) {
  403. $compare->message = '';
  404. return parent::testMessage($compare);
  405. }
  406. }
  407. class TestOfMockExpectations extends UnitTestCase {
  408. private $test;
  409. function setUp() {
  410. $this->test = new MockSimpleTestCase();
  411. }
  412. function getMockedTest() {
  413. return $this->test;
  414. }
  415. function testSettingExpectationOnNonMethodThrowsError() {
  416. $mock = new MockDummyWithInjectedTestCase();
  417. $this->expectError();
  418. $mock->expectMaximumCallCount('aMissingMethod', 2);
  419. }
  420. function testMaxCallsDetectsOverrun() {
  421. $this->test->expectOnce('assert', array(new MemberExpectation('count', 2), 3));
  422. $mock = new MockDummyWithInjectedTestCase();
  423. $mock->expectMaximumCallCount('aMethod', 2);
  424. $mock->aMethod();
  425. $mock->aMethod();
  426. $mock->aMethod();
  427. $mock->mock->atTestEnd('testSomething', $this->test);
  428. }
  429. function testTallyOnMaxCallsSendsPassOnUnderrun() {
  430. $this->test->expectOnce('assert', array(new MemberExpectation('count', 2), 2));
  431. $mock = new MockDummyWithInjectedTestCase();
  432. $mock->expectMaximumCallCount("aMethod", 2);
  433. $mock->aMethod();
  434. $mock->aMethod();
  435. $mock->mock->atTestEnd('testSomething', $this->test);
  436. }
  437. function testExpectNeverDetectsOverrun() {
  438. $this->test->expectOnce('assert', array(new MemberExpectation('count', 0), 1));
  439. $mock = new MockDummyWithInjectedTestCase();
  440. $mock->expectNever('aMethod');
  441. $mock->aMethod();
  442. $mock->mock->atTestEnd('testSomething', $this->test);
  443. }
  444. function testTallyOnExpectNeverStillSendsPassOnUnderrun() {
  445. $this->test->expectOnce('assert', array(new MemberExpectation('count', 0), 0));
  446. $mock = new MockDummyWithInjectedTestCase();
  447. $mock->expectNever('aMethod');
  448. $mock->mock->atTestEnd('testSomething', $this->test);
  449. }
  450. function testMinCalls() {
  451. $this->test->expectOnce('assert', array(new MemberExpectation('count', 2), 2));
  452. $mock = new MockDummyWithInjectedTestCase();
  453. $mock->expectMinimumCallCount('aMethod', 2);
  454. $mock->aMethod();
  455. $mock->aMethod();
  456. $mock->mock->atTestEnd('testSomething', $this->test);
  457. }
  458. function testFailedNever() {
  459. $this->test->expectOnce('assert', array(new MemberExpectation('count', 0), 1));
  460. $mock = new MockDummyWithInjectedTestCase();
  461. $mock->expectNever('aMethod');
  462. $mock->aMethod();
  463. $mock->mock->atTestEnd('testSomething', $this->test);
  464. }
  465. function testUnderOnce() {
  466. $this->test->expectOnce('assert', array(new MemberExpectation('count', 1), 0));
  467. $mock = new MockDummyWithInjectedTestCase();
  468. $mock->expectOnce('aMethod');
  469. $mock->mock->atTestEnd('testSomething', $this->test);
  470. }
  471. function testOverOnce() {
  472. $this->test->expectOnce('assert', array(new MemberExpectation('count', 1), 2));
  473. $mock = new MockDummyWithInjectedTestCase();
  474. $mock->expectOnce('aMethod');
  475. $mock->aMethod();
  476. $mock->aMethod();
  477. $mock->mock->atTestEnd('testSomething', $this->test);
  478. }
  479. function testUnderAtLeastOnce() {
  480. $this->test->expectOnce('assert', array(new MemberExpectation('count', 1), 0));
  481. $mock = new MockDummyWithInjectedTestCase();
  482. $mock->expectAtLeastOnce("aMethod");
  483. $mock->mock->atTestEnd('testSomething', $this->test);
  484. }
  485. function testZeroArguments() {
  486. $this->test->expectOnce('assert',
  487. array(new MemberExpectation('expected', array()), array(), '*'));
  488. $mock = new MockDummyWithInjectedTestCase();
  489. $mock->expect('aMethod', array());
  490. $mock->aMethod();
  491. $mock->mock->atTestEnd('testSomething', $this->test);
  492. }
  493. function testExpectedArguments() {
  494. $this->test->expectOnce('assert',
  495. array(new MemberExpectation('expected', array(1, 2, 3)), array(1, 2, 3), '*'));
  496. $mock = new MockDummyWithInjectedTestCase();
  497. $mock->expect('aMethod', array(1, 2, 3));
  498. $mock->aMethod(1, 2, 3);
  499. $mock->mock->atTestEnd('testSomething', $this->test);
  500. }
  501. function testFailedArguments() {
  502. $this->test->expectOnce('assert',
  503. array(new MemberExpectation('expected', array('this')), array('that'), '*'));
  504. $mock = new MockDummyWithInjectedTestCase();
  505. $mock->expect('aMethod', array('this'));
  506. $mock->aMethod('that');
  507. $mock->mock->atTestEnd('testSomething', $this->test);
  508. }
  509. function testWildcardsAreTranslatedToAnythingExpectations() {
  510. $this->test->expectOnce('assert',
  511. array(new MemberExpectation('expected',
  512. array(new AnythingExpectation(),
  513. 123,
  514. new AnythingExpectation())),
  515. array(100, 123, 101), '*'));
  516. $mock = new MockDummyWithInjectedTestCase($this);
  517. $mock->expect("aMethod", array('*', 123, '*'));
  518. $mock->aMethod(100, 123, 101);
  519. $mock->mock->atTestEnd('testSomething', $this->test);
  520. }
  521. function testSpecificPassingSequence() {
  522. $this->test->expectAt(0, 'assert',
  523. array(new MemberExpectation('expected', array(1, 2, 3)), array(1, 2, 3), '*'));
  524. $this->test->expectAt(1, 'assert',
  525. array(new MemberExpectation('expected', array('Hello')), array('Hello'), '*'));
  526. $mock = new MockDummyWithInjectedTestCase();
  527. $mock->expectAt(1, 'aMethod', array(1, 2, 3));
  528. $mock->expectAt(2, 'aMethod', array('Hello'));
  529. $mock->aMethod();
  530. $mock->aMethod(1, 2, 3);
  531. $mock->aMethod('Hello');
  532. $mock->aMethod();
  533. $mock->mock->atTestEnd('testSomething', $this->test);
  534. }
  535. function testNonArrayForExpectedParametersGivesError() {
  536. $mock = new MockDummyWithInjectedTestCase();
  537. $this->expectError(new PatternExpectation('/\$args.*not an array/i'));
  538. $mock->expect("aMethod", "foo");
  539. $mock->aMethod();
  540. $mock->mock->atTestEnd('testSomething', $this->test);
  541. }
  542. }
  543. class TestOfMockComparisons extends UnitTestCase {
  544. function testEqualComparisonOfMocksDoesNotCrash() {
  545. $expectation = new EqualExpectation(new MockDummy());
  546. $this->assertTrue($expectation->test(new MockDummy(), true));
  547. }
  548. function testIdenticalComparisonOfMocksDoesNotCrash() {
  549. $expectation = new IdenticalExpectation(new MockDummy());
  550. $this->assertTrue($expectation->test(new MockDummy()));
  551. }
  552. }
  553. class ClassWithSpecialMethods {
  554. function __get($name) { }
  555. function __set($name, $value) { }
  556. function __isset($name) { }
  557. function __unset($name) { }
  558. function __call($method, $arguments) { }
  559. function __toString() { }
  560. }
  561. Mock::generate('ClassWithSpecialMethods');
  562. class TestOfSpecialMethodsAfterPHP51 extends UnitTestCase {
  563. function skip() {
  564. $this->skipIf(version_compare(phpversion(), '5.1', '<'), '__isset and __unset overloading not tested unless PHP 5.1+');
  565. }
  566. function testCanEmulateIsset() {
  567. $mock = new MockClassWithSpecialMethods();
  568. $mock->returnsByValue('__isset', true);
  569. $this->assertIdentical(isset($mock->a), true);
  570. }
  571. function testCanExpectUnset() {
  572. $mock = new MockClassWithSpecialMethods();
  573. $mock->expectOnce('__unset', array('a'));
  574. unset($mock->a);
  575. }
  576. }
  577. class TestOfSpecialMethods extends UnitTestCase {
  578. function skip() {
  579. $this->skipIf(version_compare(phpversion(), '5', '<'), 'Overloading not tested unless PHP 5+');
  580. }
  581. function testCanMockTheThingAtAll() {
  582. $mock = new MockClassWithSpecialMethods();
  583. }
  584. function testReturnFromSpecialAccessor() {
  585. $mock = new MockClassWithSpecialMethods();
  586. $mock->returnsByValue('__get', '1st Return', array('first'));
  587. $mock->returnsByValue('__get', '2nd Return', array('second'));
  588. $this->assertEqual($mock->first, '1st Return');
  589. $this->assertEqual($mock->second, '2nd Return');
  590. }
  591. function testcanExpectTheSettingOfValue() {
  592. $mock = new MockClassWithSpecialMethods();
  593. $mock->expectOnce('__set', array('a', 'A'));
  594. $mock->a = 'A';
  595. }
  596. function testCanSimulateAnOverloadmethod() {
  597. $mock = new MockClassWithSpecialMethods();
  598. $mock->expectOnce('__call', array('amOverloaded', array('A')));
  599. $mock->returnsByValue('__call', 'aaa');
  600. $this->assertIdentical($mock->amOverloaded('A'), 'aaa');
  601. }
  602. function testToStringMagic() {
  603. $mock = new MockClassWithSpecialMethods();
  604. $mock->expectOnce('__toString');
  605. $mock->returnsByValue('__toString', 'AAA');
  606. ob_start();
  607. print $mock;
  608. $output = ob_get_contents();
  609. ob_end_clean();
  610. $this->assertEqual($output, 'AAA');
  611. }
  612. }
  613. class WithStaticMethod {
  614. static function aStaticMethod() { }
  615. }
  616. Mock::generate('WithStaticMethod');
  617. class TestOfMockingClassesWithStaticMethods extends UnitTestCase {
  618. function testStaticMethodIsMockedAsStatic() {
  619. $mock = new WithStaticMethod();
  620. $reflection = new ReflectionClass($mock);
  621. $method = $reflection->getMethod('aStaticMethod');
  622. $this->assertTrue($method->isStatic());
  623. }
  624. }
  625. class MockTestException extends Exception { }
  626. class TestOfThrowingExceptionsFromMocks extends UnitTestCase {
  627. function testCanThrowOnMethodCall() {
  628. $mock = new MockDummy();
  629. $mock->throwOn('aMethod');
  630. $this->expectException();
  631. $mock->aMethod();
  632. }
  633. function testCanThrowSpecificExceptionOnMethodCall() {
  634. $mock = new MockDummy();
  635. $mock->throwOn('aMethod', new MockTestException());
  636. $this->expectException();
  637. $mock->aMethod();
  638. }
  639. function testThrowsOnlyWhenCallSignatureMatches() {
  640. $mock = new MockDummy();
  641. $mock->throwOn('aMethod', new MockTestException(), array(3));
  642. $mock->aMethod(1);
  643. $mock->aMethod(2);
  644. $this->expectException();
  645. $mock->aMethod(3);
  646. }
  647. function testCanThrowOnParticularInvocation() {
  648. $mock = new MockDummy();
  649. $mock->throwAt(2, 'aMethod', new MockTestException());
  650. $mock->aMethod();
  651. $mock->aMethod();
  652. $this->expectException();
  653. $mock->aMethod();
  654. }
  655. }
  656. class TestOfThrowingErrorsFromMocks extends UnitTestCase {
  657. function testCanGenerateErrorFromMethodCall() {
  658. $mock = new MockDummy();
  659. $mock->errorOn('aMethod', 'Ouch!');
  660. $this->expectError('Ouch!');
  661. $mock->aMethod();
  662. }
  663. function testGeneratesErrorOnlyWhenCallSignatureMatches() {
  664. $mock = new MockDummy();
  665. $mock->errorOn('aMethod', 'Ouch!', array(3));
  666. $mock->aMethod(1);
  667. $mock->aMethod(2);
  668. $this->expectError();
  669. $mock->aMethod(3);
  670. }
  671. function testCanGenerateErrorOnParticularInvocation() {
  672. $mock = new MockDummy();
  673. $mock->errorAt(2, 'aMethod', 'Ouch!');
  674. $mock->aMethod();
  675. $mock->aMethod();
  676. $this->expectError();
  677. $mock->aMethod();
  678. }
  679. }
  680. Mock::generatePartial('Dummy', 'TestDummy', array('anotherMethod', 'aReferenceMethod'));
  681. class TestOfPartialMocks extends UnitTestCase {
  682. function testMethodReplacementWithNoBehaviourReturnsNull() {
  683. $mock = new TestDummy();
  684. $this->assertEqual($mock->aMethod(99), 99);
  685. $this->assertNull($mock->anotherMethod());
  686. }
  687. function testSettingReturns() {
  688. $mock = new TestDummy();
  689. $mock->returnsByValue('anotherMethod', 33, array(3));
  690. $mock->returnsByValue('anotherMethod', 22);
  691. $mock->returnsByValueAt(2, 'anotherMethod', 44, array(3));
  692. $this->assertEqual($mock->anotherMethod(), 22);
  693. $this->assertEqual($mock->anotherMethod(3), 33);
  694. $this->assertEqual($mock->anotherMethod(3), 44);
  695. }
  696. function testSetReturnReferenceGivesOriginal() {
  697. $mock = new TestDummy();
  698. $object = 99;
  699. $mock->returnsByReferenceAt(0, 'aReferenceMethod', $object, array(3));
  700. $this->assertReference($mock->aReferenceMethod(3), $object);
  701. }
  702. function testReturnsAtGivesOriginalObjectHandle() {
  703. $mock = new TestDummy();
  704. $object = new Dummy();
  705. $mock->returnsAt(0, 'anotherMethod', $object, array(3));
  706. $this->assertSame($mock->anotherMethod(3), $object);
  707. }
  708. function testExpectations() {
  709. $mock = new TestDummy();
  710. $mock->expectCallCount('anotherMethod', 2);
  711. $mock->expect('anotherMethod', array(77));
  712. $mock->expectAt(1, 'anotherMethod', array(66));
  713. $mock->anotherMethod(77);
  714. $mock->anotherMethod(66);
  715. }
  716. function testSettingExpectationOnMissingMethodThrowsError() {
  717. $mock = new TestDummy();
  718. $this->expectError();
  719. $mock->expectCallCount('aMissingMethod', 2);
  720. }
  721. }
  722. class ConstructorSuperClass {
  723. function ConstructorSuperClass() { }
  724. }
  725. class ConstructorSubClass extends ConstructorSuperClass { }
  726. class TestOfPHP4StyleSuperClassConstruct extends UnitTestCase {
  727. function testBasicConstruct() {
  728. Mock::generate('ConstructorSubClass');
  729. $mock = new MockConstructorSubClass();
  730. $this->assertIsA($mock, 'ConstructorSubClass');
  731. $this->assertTrue(method_exists($mock, 'ConstructorSuperClass'));
  732. }
  733. }
  734. class TestOfPHP5StaticMethodMocking extends UnitTestCase {
  735. function testCanCreateAMockObjectWithStaticMethodsWithoutError() {
  736. eval('
  737. class SimpleObjectContainingStaticMethod {
  738. static function someStatic() { }
  739. }
  740. ');
  741. Mock::generate('SimpleObjectContainingStaticMethod');
  742. }
  743. }
  744. class TestOfPHP5AbstractMethodMocking extends UnitTestCase {
  745. function testCanCreateAMockObjectFromAnAbstractWithProperFunctionDeclarations() {
  746. eval('
  747. abstract class SimpleAbstractClassContainingAbstractMethods {
  748. abstract function anAbstract();
  749. abstract function anAbstractWithParameter($foo);
  750. abstract function anAbstractWithMultipleParameters($foo, $bar);
  751. }
  752. ');
  753. Mock::generate('SimpleAbstractClassContainingAbstractMethods');
  754. $this->assertTrue(
  755. method_exists(
  756. // Testing with class name alone does not work in PHP 5.0
  757. new MockSimpleAbstractClassContainingAbstractMethods,
  758. 'anAbstract'
  759. )
  760. );
  761. $this->assertTrue(
  762. method_exists(
  763. new MockSimpleAbstractClassContainingAbstractMethods,
  764. 'anAbstractWithParameter'
  765. )
  766. );
  767. $this->assertTrue(
  768. method_exists(
  769. new MockSimpleAbstractClassContainingAbstractMethods,
  770. 'anAbstractWithMultipleParameters'
  771. )
  772. );
  773. }
  774. function testMethodsDefinedAsAbstractInParentShouldHaveFullSignature() {
  775. eval('
  776. abstract class SimpleParentAbstractClassContainingAbstractMethods {
  777. abstract function anAbstract();
  778. abstract function anAbstractWithParameter($foo);
  779. abstract function anAbstractWithMultipleParameters($foo, $bar);
  780. }
  781. class SimpleChildAbstractClassContainingAbstractMethods extends SimpleParentAbstractClassContainingAbstractMethods {
  782. function anAbstract(){}
  783. function anAbstractWithParameter($foo){}
  784. function anAbstractWithMultipleParameters($foo, $bar){}
  785. }
  786. class EvenDeeperEmptyChildClass extends SimpleChildAbstractClassContainingAbstractMethods {}
  787. ');
  788. Mock::generate('SimpleChildAbstractClassContainingAbstractMethods');
  789. $this->assertTrue(
  790. method_exists(
  791. new MockSimpleChildAbstractClassContainingAbstractMethods,
  792. 'anAbstract'
  793. )
  794. );
  795. $this->assertTrue(
  796. method_exists(
  797. new MockSimpleChildAbstractClassContainingAbstractMethods,
  798. 'anAbstractWithParameter'
  799. )
  800. );
  801. $this->assertTrue(
  802. method_exists(
  803. new MockSimpleChildAbstractClassContainingAbstractMethods,
  804. 'anAbstractWithMultipleParameters'
  805. )
  806. );
  807. Mock::generate('EvenDeeperEmptyChildClass');
  808. $this->assertTrue(
  809. method_exists(
  810. new MockEvenDeeperEmptyChildClass,
  811. 'anAbstract'
  812. )
  813. );
  814. $this->assertTrue(
  815. method_exists(
  816. new MockEvenDeeperEmptyChildClass,
  817. 'anAbstractWithParameter'
  818. )
  819. );
  820. $this->assertTrue(
  821. method_exists(
  822. new MockEvenDeeperEmptyChildClass,
  823. 'anAbstractWithMultipleParameters'
  824. )
  825. );
  826. }
  827. }
  828. class DummyWithProtected
  829. {
  830. public function aMethodCallsProtected() { return $this->aProtectedMethod(); }
  831. protected function aProtectedMethod() { return true; }
  832. }
  833. Mock::generatePartial('DummyWithProtected', 'TestDummyWithProtected', array('aProtectedMethod'));
  834. class TestOfProtectedMethodPartialMocks extends UnitTestCase
  835. {
  836. function testProtectedMethodExists() {
  837. $this->assertTrue(
  838. method_exists(
  839. new TestDummyWithProtected,
  840. 'aProtectedMethod'
  841. )
  842. );
  843. }
  844. function testProtectedMethodIsCalled() {
  845. $object = new DummyWithProtected();
  846. $this->assertTrue($object->aMethodCallsProtected(), 'ensure original was called');
  847. }
  848. function testMockedMethodIsCalled() {
  849. $object = new TestDummyWithProtected();
  850. $object->returnsByValue('aProtectedMethod', false);
  851. $this->assertFalse($object->aMethodCallsProtected());
  852. }
  853. }
  854. ?>