PageRenderTime 38ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 0ms

/branches/1.0/test/mock_objects_test.php

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