MockObjectTest.php 33KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076
  1. <?php
  2. /*
  3. * This file is part of the phpunit-mock-objects package.
  4. *
  5. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. use PHPUnit\Framework\MockObject\MockObject;
  11. use PHPUnit\Framework\TestCase;
  12. use PHPUnit\Framework\ExpectationFailedException;
  13. class MockObjectTest extends TestCase
  14. {
  15. public function testMockedMethodIsNeverCalled()
  16. {
  17. $mock = $this->getMockBuilder(AnInterface::class)
  18. ->getMock();
  19. $mock->expects($this->never())
  20. ->method('doSomething');
  21. }
  22. public function testMockedMethodIsNeverCalledWithParameter()
  23. {
  24. $mock = $this->getMockBuilder(SomeClass::class)
  25. ->getMock();
  26. $mock->expects($this->never())
  27. ->method('doSomething')
  28. ->with('someArg');
  29. }
  30. /**
  31. * @doesNotPerformAssertions
  32. */
  33. public function testMockedMethodIsNotCalledWhenExpectsAnyWithParameter()
  34. {
  35. $mock = $this->getMockBuilder(SomeClass::class)
  36. ->getMock();
  37. $mock->expects($this->any())
  38. ->method('doSomethingElse')
  39. ->with('someArg');
  40. }
  41. /**
  42. * @doesNotPerformAssertions
  43. */
  44. public function testMockedMethodIsNotCalledWhenMethodSpecifiedDirectlyWithParameter()
  45. {
  46. $mock = $this->getMockBuilder(SomeClass::class)
  47. ->getMock();
  48. $mock->method('doSomethingElse')
  49. ->with('someArg');
  50. }
  51. public function testMockedMethodIsCalledAtLeastOnce()
  52. {
  53. $mock = $this->getMockBuilder(AnInterface::class)
  54. ->getMock();
  55. $mock->expects($this->atLeastOnce())
  56. ->method('doSomething');
  57. $mock->doSomething();
  58. }
  59. public function testMockedMethodIsCalledAtLeastOnce2()
  60. {
  61. $mock = $this->getMockBuilder(AnInterface::class)
  62. ->getMock();
  63. $mock->expects($this->atLeastOnce())
  64. ->method('doSomething');
  65. $mock->doSomething();
  66. $mock->doSomething();
  67. }
  68. public function testMockedMethodIsCalledAtLeastTwice()
  69. {
  70. $mock = $this->getMockBuilder(AnInterface::class)
  71. ->getMock();
  72. $mock->expects($this->atLeast(2))
  73. ->method('doSomething');
  74. $mock->doSomething();
  75. $mock->doSomething();
  76. }
  77. public function testMockedMethodIsCalledAtLeastTwice2()
  78. {
  79. $mock = $this->getMockBuilder(AnInterface::class)
  80. ->getMock();
  81. $mock->expects($this->atLeast(2))
  82. ->method('doSomething');
  83. $mock->doSomething();
  84. $mock->doSomething();
  85. $mock->doSomething();
  86. }
  87. public function testMockedMethodIsCalledAtMostTwice()
  88. {
  89. $mock = $this->getMockBuilder(AnInterface::class)
  90. ->getMock();
  91. $mock->expects($this->atMost(2))
  92. ->method('doSomething');
  93. $mock->doSomething();
  94. $mock->doSomething();
  95. }
  96. public function testMockedMethodIsCalledAtMosttTwice2()
  97. {
  98. $mock = $this->getMockBuilder(AnInterface::class)
  99. ->getMock();
  100. $mock->expects($this->atMost(2))
  101. ->method('doSomething');
  102. $mock->doSomething();
  103. }
  104. public function testMockedMethodIsCalledOnce()
  105. {
  106. $mock = $this->getMockBuilder(AnInterface::class)
  107. ->getMock();
  108. $mock->expects($this->once())
  109. ->method('doSomething');
  110. $mock->doSomething();
  111. }
  112. public function testMockedMethodIsCalledOnceWithParameter()
  113. {
  114. $mock = $this->getMockBuilder(SomeClass::class)
  115. ->getMock();
  116. $mock->expects($this->once())
  117. ->method('doSomethingElse')
  118. ->with($this->equalTo('something'));
  119. $mock->doSomethingElse('something');
  120. }
  121. public function testMockedMethodIsCalledExactly()
  122. {
  123. $mock = $this->getMockBuilder(AnInterface::class)
  124. ->getMock();
  125. $mock->expects($this->exactly(2))
  126. ->method('doSomething');
  127. $mock->doSomething();
  128. $mock->doSomething();
  129. }
  130. public function testStubbedException()
  131. {
  132. $mock = $this->getMockBuilder(AnInterface::class)
  133. ->getMock();
  134. $mock->expects($this->any())
  135. ->method('doSomething')
  136. ->will($this->throwException(new \Exception()));
  137. $this->expectException(\Exception::class);
  138. $mock->doSomething();
  139. }
  140. public function testStubbedWillThrowException()
  141. {
  142. $mock = $this->getMockBuilder(AnInterface::class)
  143. ->getMock();
  144. $mock->expects($this->any())
  145. ->method('doSomething')
  146. ->willThrowException(new \Exception());
  147. $this->expectException(\Exception::class);
  148. $mock->doSomething();
  149. }
  150. public function testStubbedReturnValue()
  151. {
  152. $mock = $this->getMockBuilder(AnInterface::class)
  153. ->getMock();
  154. $mock->expects($this->any())
  155. ->method('doSomething')
  156. ->will($this->returnValue('something'));
  157. $this->assertEquals('something', $mock->doSomething());
  158. $mock = $this->getMockBuilder(AnInterface::class)
  159. ->getMock();
  160. $mock->expects($this->any())
  161. ->method('doSomething')
  162. ->willReturn('something');
  163. $this->assertEquals('something', $mock->doSomething());
  164. }
  165. public function testStubbedReturnValueMap()
  166. {
  167. $map = [
  168. ['a', 'b', 'c', 'd'],
  169. ['e', 'f', 'g', 'h']
  170. ];
  171. $mock = $this->getMockBuilder(AnInterface::class)
  172. ->getMock();
  173. $mock->expects($this->any())
  174. ->method('doSomething')
  175. ->will($this->returnValueMap($map));
  176. $this->assertEquals('d', $mock->doSomething('a', 'b', 'c'));
  177. $this->assertEquals('h', $mock->doSomething('e', 'f', 'g'));
  178. $this->assertEquals(null, $mock->doSomething('foo', 'bar'));
  179. $mock = $this->getMockBuilder(AnInterface::class)
  180. ->getMock();
  181. $mock->expects($this->any())
  182. ->method('doSomething')
  183. ->willReturnMap($map);
  184. $this->assertEquals('d', $mock->doSomething('a', 'b', 'c'));
  185. $this->assertEquals('h', $mock->doSomething('e', 'f', 'g'));
  186. $this->assertEquals(null, $mock->doSomething('foo', 'bar'));
  187. }
  188. public function testStubbedReturnArgument()
  189. {
  190. $mock = $this->getMockBuilder(AnInterface::class)
  191. ->getMock();
  192. $mock->expects($this->any())
  193. ->method('doSomething')
  194. ->will($this->returnArgument(1));
  195. $this->assertEquals('b', $mock->doSomething('a', 'b'));
  196. $mock = $this->getMockBuilder(AnInterface::class)
  197. ->getMock();
  198. $mock->expects($this->any())
  199. ->method('doSomething')
  200. ->willReturnArgument(1);
  201. $this->assertEquals('b', $mock->doSomething('a', 'b'));
  202. }
  203. public function testFunctionCallback()
  204. {
  205. $mock = $this->getMockBuilder(SomeClass::class)
  206. ->setMethods(['doSomething'])
  207. ->getMock();
  208. $mock->expects($this->once())
  209. ->method('doSomething')
  210. ->will($this->returnCallback('functionCallback'));
  211. $this->assertEquals('pass', $mock->doSomething('foo', 'bar'));
  212. $mock = $this->getMockBuilder(SomeClass::class)
  213. ->setMethods(['doSomething'])
  214. ->getMock();
  215. $mock->expects($this->once())
  216. ->method('doSomething')
  217. ->willReturnCallback('functionCallback');
  218. $this->assertEquals('pass', $mock->doSomething('foo', 'bar'));
  219. }
  220. public function testStubbedReturnSelf()
  221. {
  222. $mock = $this->getMockBuilder(AnInterface::class)
  223. ->getMock();
  224. $mock->expects($this->any())
  225. ->method('doSomething')
  226. ->will($this->returnSelf());
  227. $this->assertEquals($mock, $mock->doSomething());
  228. $mock = $this->getMockBuilder(AnInterface::class)
  229. ->getMock();
  230. $mock->expects($this->any())
  231. ->method('doSomething')
  232. ->willReturnSelf();
  233. $this->assertEquals($mock, $mock->doSomething());
  234. }
  235. public function testStubbedReturnOnConsecutiveCalls()
  236. {
  237. $mock = $this->getMockBuilder(AnInterface::class)
  238. ->getMock();
  239. $mock->expects($this->any())
  240. ->method('doSomething')
  241. ->will($this->onConsecutiveCalls('a', 'b', 'c'));
  242. $this->assertEquals('a', $mock->doSomething());
  243. $this->assertEquals('b', $mock->doSomething());
  244. $this->assertEquals('c', $mock->doSomething());
  245. $mock = $this->getMockBuilder(AnInterface::class)
  246. ->getMock();
  247. $mock->expects($this->any())
  248. ->method('doSomething')
  249. ->willReturnOnConsecutiveCalls('a', 'b', 'c');
  250. $this->assertEquals('a', $mock->doSomething());
  251. $this->assertEquals('b', $mock->doSomething());
  252. $this->assertEquals('c', $mock->doSomething());
  253. }
  254. public function testStaticMethodCallback()
  255. {
  256. $mock = $this->getMockBuilder(SomeClass::class)
  257. ->setMethods(['doSomething'])
  258. ->getMock();
  259. $mock->expects($this->once())
  260. ->method('doSomething')
  261. ->will($this->returnCallback(['MethodCallback', 'staticCallback']));
  262. $this->assertEquals('pass', $mock->doSomething('foo', 'bar'));
  263. }
  264. public function testPublicMethodCallback()
  265. {
  266. $mock = $this->getMockBuilder(SomeClass::class)
  267. ->setMethods(['doSomething'])
  268. ->getMock();
  269. $mock->expects($this->once())
  270. ->method('doSomething')
  271. ->will($this->returnCallback([new MethodCallback, 'nonStaticCallback']));
  272. $this->assertEquals('pass', $mock->doSomething('foo', 'bar'));
  273. }
  274. public function testMockClassOnlyGeneratedOnce()
  275. {
  276. $mock1 = $this->getMockBuilder(AnInterface::class)
  277. ->getMock();
  278. $mock2 = $this->getMockBuilder(AnInterface::class)
  279. ->getMock();
  280. $this->assertEquals(get_class($mock1), get_class($mock2));
  281. }
  282. public function testMockClassDifferentForPartialMocks()
  283. {
  284. $mock1 = $this->getMockBuilder(PartialMockTestClass::class)
  285. ->getMock();
  286. $mock2 = $this->getMockBuilder(PartialMockTestClass::class)
  287. ->setMethods(['doSomething'])
  288. ->getMock();
  289. $mock3 = $this->getMockBuilder(PartialMockTestClass::class)
  290. ->setMethods(['doSomething'])
  291. ->getMock();
  292. $mock4 = $this->getMockBuilder(PartialMockTestClass::class)
  293. ->setMethods(['doAnotherThing'])
  294. ->getMock();
  295. $mock5 = $this->getMockBuilder(PartialMockTestClass::class)
  296. ->setMethods(['doAnotherThing'])
  297. ->getMock();
  298. $this->assertNotEquals(get_class($mock1), get_class($mock2));
  299. $this->assertNotEquals(get_class($mock1), get_class($mock3));
  300. $this->assertNotEquals(get_class($mock1), get_class($mock4));
  301. $this->assertNotEquals(get_class($mock1), get_class($mock5));
  302. $this->assertEquals(get_class($mock2), get_class($mock3));
  303. $this->assertNotEquals(get_class($mock2), get_class($mock4));
  304. $this->assertNotEquals(get_class($mock2), get_class($mock5));
  305. $this->assertEquals(get_class($mock4), get_class($mock5));
  306. }
  307. public function testMockClassStoreOverrulable()
  308. {
  309. $mock1 = $this->getMockBuilder(PartialMockTestClass::class)
  310. ->getMock();
  311. $mock2 = $this->getMockBuilder(PartialMockTestClass::class)
  312. ->setMockClassName('MyMockClassNameForPartialMockTestClass1')
  313. ->getMock();
  314. $mock3 = $this->getMockBuilder(PartialMockTestClass::class)
  315. ->getMock();
  316. $mock4 = $this->getMockBuilder(PartialMockTestClass::class)
  317. ->setMethods(['doSomething'])
  318. ->setMockClassName('AnotherMockClassNameForPartialMockTestClass')
  319. ->getMock();
  320. $mock5 = $this->getMockBuilder(PartialMockTestClass::class)
  321. ->setMockClassName('MyMockClassNameForPartialMockTestClass2')
  322. ->getMock();
  323. $this->assertNotEquals(get_class($mock1), get_class($mock2));
  324. $this->assertEquals(get_class($mock1), get_class($mock3));
  325. $this->assertNotEquals(get_class($mock1), get_class($mock4));
  326. $this->assertNotEquals(get_class($mock2), get_class($mock3));
  327. $this->assertNotEquals(get_class($mock2), get_class($mock4));
  328. $this->assertNotEquals(get_class($mock2), get_class($mock5));
  329. $this->assertNotEquals(get_class($mock3), get_class($mock4));
  330. $this->assertNotEquals(get_class($mock3), get_class($mock5));
  331. $this->assertNotEquals(get_class($mock4), get_class($mock5));
  332. }
  333. public function testGetMockWithFixedClassNameCanProduceTheSameMockTwice()
  334. {
  335. $mock = $this->getMockBuilder(stdClass::class)->setMockClassName('FixedName')->getMock();
  336. $mock = $this->getMockBuilder(stdClass::class)->setMockClassName('FixedName')->getMock();
  337. $this->assertInstanceOf(stdClass::class, $mock);
  338. }
  339. public function testOriginalConstructorSettingConsidered()
  340. {
  341. $mock1 = $this->getMockBuilder(PartialMockTestClass::class)
  342. ->getMock();
  343. $mock2 = $this->getMockBuilder(PartialMockTestClass::class)
  344. ->disableOriginalConstructor()
  345. ->getMock();
  346. $this->assertTrue($mock1->constructorCalled);
  347. $this->assertFalse($mock2->constructorCalled);
  348. }
  349. public function testOriginalCloneSettingConsidered()
  350. {
  351. $mock1 = $this->getMockBuilder(PartialMockTestClass::class)
  352. ->getMock();
  353. $mock2 = $this->getMockBuilder(PartialMockTestClass::class)
  354. ->disableOriginalClone()
  355. ->getMock();
  356. $this->assertNotEquals(get_class($mock1), get_class($mock2));
  357. }
  358. public function testGetMockForAbstractClass()
  359. {
  360. $mock = $this->getMockBuilder(AbstractMockTestClass::class)
  361. ->getMock();
  362. $mock->expects($this->never())
  363. ->method('doSomething');
  364. }
  365. /**
  366. * @dataProvider traversableProvider
  367. */
  368. public function testGetMockForTraversable($type)
  369. {
  370. $mock = $this->getMockBuilder($type)
  371. ->getMock();
  372. $this->assertInstanceOf(Traversable::class, $mock);
  373. }
  374. public function testMultipleInterfacesCanBeMockedInSingleObject()
  375. {
  376. $mock = $this->getMockBuilder([AnInterface::class, AnotherInterface::class])
  377. ->getMock();
  378. $this->assertInstanceOf(AnInterface::class, $mock);
  379. $this->assertInstanceOf(AnotherInterface::class, $mock);
  380. }
  381. public function testGetMockForTrait()
  382. {
  383. $mock = $this->getMockForTrait(AbstractTrait::class);
  384. $mock->expects($this->never())
  385. ->method('doSomething');
  386. $parent = get_parent_class($mock);
  387. $traits = class_uses($parent, false);
  388. $this->assertContains(AbstractTrait::class, $traits);
  389. }
  390. public function testClonedMockObjectShouldStillEqualTheOriginal()
  391. {
  392. $a = $this->getMockBuilder(stdClass::class)
  393. ->getMock();
  394. $b = clone $a;
  395. $this->assertEquals($a, $b);
  396. }
  397. public function testMockObjectsConstructedIndepentantlyShouldBeEqual()
  398. {
  399. $a = $this->getMockBuilder(stdClass::class)
  400. ->getMock();
  401. $b = $this->getMockBuilder(stdClass::class)
  402. ->getMock();
  403. $this->assertEquals($a, $b);
  404. }
  405. public function testMockObjectsConstructedIndepentantlyShouldNotBeTheSame()
  406. {
  407. $a = $this->getMockBuilder(stdClass::class)
  408. ->getMock();
  409. $b = $this->getMockBuilder(stdClass::class)
  410. ->getMock();
  411. $this->assertNotSame($a, $b);
  412. }
  413. public function testClonedMockObjectCanBeUsedInPlaceOfOriginalOne()
  414. {
  415. $x = $this->getMockBuilder(stdClass::class)
  416. ->getMock();
  417. $y = clone $x;
  418. $mock = $this->getMockBuilder(stdClass::class)
  419. ->setMethods(['foo'])
  420. ->getMock();
  421. $mock->expects($this->once())
  422. ->method('foo')
  423. ->with($this->equalTo($x));
  424. $mock->foo($y);
  425. }
  426. public function testClonedMockObjectIsNotIdenticalToOriginalOne()
  427. {
  428. $x = $this->getMockBuilder(stdClass::class)
  429. ->getMock();
  430. $y = clone $x;
  431. $mock = $this->getMockBuilder(stdClass::class)
  432. ->setMethods(['foo'])
  433. ->getMock();
  434. $mock->expects($this->once())
  435. ->method('foo')
  436. ->with($this->logicalNot($this->identicalTo($x)));
  437. $mock->foo($y);
  438. }
  439. public function testObjectMethodCallWithArgumentCloningEnabled()
  440. {
  441. $expectedObject = new stdClass;
  442. $mock = $this->getMockBuilder('SomeClass')
  443. ->setMethods(['doSomethingElse'])
  444. ->enableArgumentCloning()
  445. ->getMock();
  446. $actualArguments = [];
  447. $mock->expects($this->any())
  448. ->method('doSomethingElse')
  449. ->will(
  450. $this->returnCallback(
  451. function () use (&$actualArguments) {
  452. $actualArguments = func_get_args();
  453. }
  454. )
  455. );
  456. $mock->doSomethingElse($expectedObject);
  457. $this->assertEquals(1, count($actualArguments));
  458. $this->assertEquals($expectedObject, $actualArguments[0]);
  459. $this->assertNotSame($expectedObject, $actualArguments[0]);
  460. }
  461. public function testObjectMethodCallWithArgumentCloningDisabled()
  462. {
  463. $expectedObject = new stdClass;
  464. $mock = $this->getMockBuilder('SomeClass')
  465. ->setMethods(['doSomethingElse'])
  466. ->disableArgumentCloning()
  467. ->getMock();
  468. $actualArguments = [];
  469. $mock->expects($this->any())
  470. ->method('doSomethingElse')
  471. ->will(
  472. $this->returnCallback(
  473. function () use (&$actualArguments) {
  474. $actualArguments = func_get_args();
  475. }
  476. )
  477. );
  478. $mock->doSomethingElse($expectedObject);
  479. $this->assertEquals(1, count($actualArguments));
  480. $this->assertSame($expectedObject, $actualArguments[0]);
  481. }
  482. public function testArgumentCloningOptionGeneratesUniqueMock()
  483. {
  484. $mockWithCloning = $this->getMockBuilder('SomeClass')
  485. ->setMethods(['doSomethingElse'])
  486. ->enableArgumentCloning()
  487. ->getMock();
  488. $mockWithoutCloning = $this->getMockBuilder('SomeClass')
  489. ->setMethods(['doSomethingElse'])
  490. ->disableArgumentCloning()
  491. ->getMock();
  492. $this->assertNotEquals($mockWithCloning, $mockWithoutCloning);
  493. }
  494. public function testVerificationOfMethodNameFailsWithoutParameters()
  495. {
  496. $mock = $this->getMockBuilder(SomeClass::class)
  497. ->setMethods(['right', 'wrong'])
  498. ->getMock();
  499. $mock->expects($this->once())
  500. ->method('right');
  501. $mock->wrong();
  502. try {
  503. $mock->__phpunit_verify();
  504. $this->fail('Expected exception');
  505. } catch (ExpectationFailedException $e) {
  506. $this->assertSame(
  507. 'Expectation failed for method name is equal to "right" when invoked 1 time(s).' . PHP_EOL .
  508. 'Method was expected to be called 1 times, actually called 0 times.' . PHP_EOL,
  509. $e->getMessage()
  510. );
  511. }
  512. $this->resetMockObjects();
  513. }
  514. public function testVerificationOfMethodNameFailsWithParameters()
  515. {
  516. $mock = $this->getMockBuilder(SomeClass::class)
  517. ->setMethods(['right', 'wrong'])
  518. ->getMock();
  519. $mock->expects($this->once())
  520. ->method('right');
  521. $mock->wrong();
  522. try {
  523. $mock->__phpunit_verify();
  524. $this->fail('Expected exception');
  525. } catch (ExpectationFailedException $e) {
  526. $this->assertSame(
  527. 'Expectation failed for method name is equal to "right" when invoked 1 time(s).' . PHP_EOL .
  528. 'Method was expected to be called 1 times, actually called 0 times.' . PHP_EOL,
  529. $e->getMessage()
  530. );
  531. }
  532. $this->resetMockObjects();
  533. }
  534. public function testVerificationOfMethodNameFailsWithWrongParameters()
  535. {
  536. $mock = $this->getMockBuilder(SomeClass::class)
  537. ->setMethods(['right', 'wrong'])
  538. ->getMock();
  539. $mock->expects($this->once())
  540. ->method('right')
  541. ->with(['first', 'second']);
  542. try {
  543. $mock->right(['second']);
  544. } catch (ExpectationFailedException $e) {
  545. $this->assertSame(
  546. 'Expectation failed for method name is equal to "right" when invoked 1 time(s)' . PHP_EOL .
  547. 'Parameter 0 for invocation SomeClass::right(Array (...)) does not match expected value.' . PHP_EOL .
  548. 'Failed asserting that two arrays are equal.',
  549. $e->getMessage()
  550. );
  551. }
  552. try {
  553. $mock->__phpunit_verify();
  554. // CHECKOUT THIS MORE CAREFULLY
  555. // $this->fail('Expected exception');
  556. } catch (ExpectationFailedException $e) {
  557. $this->assertSame(
  558. 'Expectation failed for method name is equal to "right" when invoked 1 time(s).' . PHP_EOL .
  559. 'Parameter 0 for invocation SomeClass::right(Array (...)) does not match expected value.' . PHP_EOL .
  560. 'Failed asserting that two arrays are equal.' . PHP_EOL .
  561. '--- Expected' . PHP_EOL .
  562. '+++ Actual' . PHP_EOL .
  563. '@@ @@' . PHP_EOL .
  564. ' Array (' . PHP_EOL .
  565. '- 0 => \'first\'' . PHP_EOL .
  566. '- 1 => \'second\'' . PHP_EOL .
  567. '+ 0 => \'second\'' . PHP_EOL,
  568. $e->getMessage()
  569. );
  570. }
  571. $this->resetMockObjects();
  572. }
  573. public function testVerificationOfNeverFailsWithEmptyParameters()
  574. {
  575. $mock = $this->getMockBuilder(SomeClass::class)
  576. ->setMethods(['right', 'wrong'])
  577. ->getMock();
  578. $mock->expects($this->never())
  579. ->method('right')
  580. ->with();
  581. try {
  582. $mock->right();
  583. $this->fail('Expected exception');
  584. } catch (ExpectationFailedException $e) {
  585. $this->assertSame(
  586. 'SomeClass::right() was not expected to be called.',
  587. $e->getMessage()
  588. );
  589. }
  590. $this->resetMockObjects();
  591. }
  592. public function testVerificationOfNeverFailsWithAnyParameters()
  593. {
  594. $mock = $this->getMockBuilder(SomeClass::class)
  595. ->setMethods(['right', 'wrong'])
  596. ->getMock();
  597. $mock->expects($this->never())
  598. ->method('right')
  599. ->withAnyParameters();
  600. try {
  601. $mock->right();
  602. $this->fail('Expected exception');
  603. } catch (ExpectationFailedException $e) {
  604. $this->assertSame(
  605. 'SomeClass::right() was not expected to be called.',
  606. $e->getMessage()
  607. );
  608. }
  609. $this->resetMockObjects();
  610. }
  611. public function testWithAnythingInsteadOfWithAnyParameters()
  612. {
  613. $mock = $this->getMockBuilder(SomeClass::class)
  614. ->setMethods(['right', 'wrong'])
  615. ->getMock();
  616. $mock->expects($this->once())
  617. ->method('right')
  618. ->with($this->anything());
  619. try {
  620. $mock->right();
  621. $this->fail('Expected exception');
  622. } catch (ExpectationFailedException $e) {
  623. $this->assertSame(
  624. 'Expectation failed for method name is equal to "right" when invoked 1 time(s)' . PHP_EOL .
  625. 'Parameter count for invocation SomeClass::right() is too low.' . PHP_EOL .
  626. 'To allow 0 or more parameters with any value, omit ->with() or use ->withAnyParameters() instead.',
  627. $e->getMessage()
  628. );
  629. }
  630. $this->resetMockObjects();
  631. }
  632. /**
  633. * See https://github.com/sebastianbergmann/phpunit-mock-objects/issues/81
  634. */
  635. public function testMockArgumentsPassedByReference()
  636. {
  637. $foo = $this->getMockBuilder('MethodCallbackByReference')
  638. ->setMethods(['bar'])
  639. ->disableOriginalConstructor()
  640. ->disableArgumentCloning()
  641. ->getMock();
  642. $foo->expects($this->any())
  643. ->method('bar')
  644. ->will($this->returnCallback([$foo, 'callback']));
  645. $a = $b = $c = 0;
  646. $foo->bar($a, $b, $c);
  647. $this->assertEquals(1, $b);
  648. }
  649. /**
  650. * See https://github.com/sebastianbergmann/phpunit-mock-objects/issues/81
  651. */
  652. public function testMockArgumentsPassedByReference2()
  653. {
  654. $foo = $this->getMockBuilder('MethodCallbackByReference')
  655. ->disableOriginalConstructor()
  656. ->disableArgumentCloning()
  657. ->getMock();
  658. $foo->expects($this->any())
  659. ->method('bar')
  660. ->will($this->returnCallback(
  661. function (&$a, &$b, $c) {
  662. $b = 1;
  663. }
  664. ));
  665. $a = $b = $c = 0;
  666. $foo->bar($a, $b, $c);
  667. $this->assertEquals(1, $b);
  668. }
  669. /**
  670. * @see https://github.com/sebastianbergmann/phpunit-mock-objects/issues/116
  671. */
  672. public function testMockArgumentsPassedByReference3()
  673. {
  674. $foo = $this->getMockBuilder('MethodCallbackByReference')
  675. ->setMethods(['bar'])
  676. ->disableOriginalConstructor()
  677. ->disableArgumentCloning()
  678. ->getMock();
  679. $a = new stdClass;
  680. $b = $c = 0;
  681. $foo->expects($this->any())
  682. ->method('bar')
  683. ->with($a, $b, $c)
  684. ->will($this->returnCallback([$foo, 'callback']));
  685. $this->assertNull($foo->bar($a, $b, $c));
  686. }
  687. /**
  688. * @see https://github.com/sebastianbergmann/phpunit/issues/796
  689. */
  690. public function testMockArgumentsPassedByReference4()
  691. {
  692. $foo = $this->getMockBuilder('MethodCallbackByReference')
  693. ->setMethods(['bar'])
  694. ->disableOriginalConstructor()
  695. ->disableArgumentCloning()
  696. ->getMock();
  697. $a = new stdClass;
  698. $b = $c = 0;
  699. $foo->expects($this->any())
  700. ->method('bar')
  701. ->with($this->isInstanceOf(stdClass::class), $b, $c)
  702. ->will($this->returnCallback([$foo, 'callback']));
  703. $this->assertNull($foo->bar($a, $b, $c));
  704. }
  705. /**
  706. * @requires extension soap
  707. */
  708. public function testCreateMockFromWsdl()
  709. {
  710. $mock = $this->getMockFromWsdl(__DIR__ . '/_fixture/GoogleSearch.wsdl', 'WsdlMock');
  711. $this->assertStringStartsWith(
  712. 'Mock_WsdlMock_',
  713. get_class($mock)
  714. );
  715. }
  716. /**
  717. * @requires extension soap
  718. */
  719. public function testCreateNamespacedMockFromWsdl()
  720. {
  721. $mock = $this->getMockFromWsdl(__DIR__ . '/_fixture/GoogleSearch.wsdl', 'My\\Space\\WsdlMock');
  722. $this->assertStringStartsWith(
  723. 'Mock_WsdlMock_',
  724. get_class($mock)
  725. );
  726. }
  727. /**
  728. * @requires extension soap
  729. */
  730. public function testCreateTwoMocksOfOneWsdlFile()
  731. {
  732. $a = $this->getMockFromWsdl(__DIR__ . '/_fixture/GoogleSearch.wsdl');
  733. $b = $this->getMockFromWsdl(__DIR__ . '/_fixture/GoogleSearch.wsdl');
  734. $this->assertStringStartsWith('Mock_GoogleSearch_', get_class($a));
  735. $this->assertEquals(get_class($a), get_class($b));
  736. }
  737. /**
  738. * @see https://github.com/sebastianbergmann/phpunit-mock-objects/issues/156
  739. * @ticket 156
  740. */
  741. public function testInterfaceWithStaticMethodCanBeStubbed()
  742. {
  743. $this->assertInstanceOf(
  744. InterfaceWithStaticMethod::class,
  745. $this->getMockBuilder(InterfaceWithStaticMethod::class)->getMock()
  746. );
  747. }
  748. public function testInvokingStubbedStaticMethodRaisesException()
  749. {
  750. $mock = $this->getMockBuilder(ClassWithStaticMethod::class)->getMock();
  751. $this->expectException(\PHPUnit\Framework\MockObject\BadMethodCallException::class);
  752. $mock->staticMethod();
  753. }
  754. /**
  755. * @see https://github.com/sebastianbergmann/phpunit-mock-objects/issues/171
  756. * @ticket 171
  757. */
  758. public function testStubForClassThatImplementsSerializableCanBeCreatedWithoutInvokingTheConstructor()
  759. {
  760. $this->assertInstanceOf(
  761. ClassThatImplementsSerializable::class,
  762. $this->getMockBuilder(ClassThatImplementsSerializable::class)
  763. ->disableOriginalConstructor()
  764. ->getMock()
  765. );
  766. }
  767. public function testGetMockForClassWithSelfTypeHint()
  768. {
  769. $this->assertInstanceOf(
  770. ClassWithSelfTypeHint::class,
  771. $this->getMockBuilder(ClassWithSelfTypeHint::class)->getMock()
  772. );
  773. }
  774. private function resetMockObjects()
  775. {
  776. $refl = new ReflectionObject($this);
  777. $refl = $refl->getParentClass();
  778. $prop = $refl->getProperty('mockObjects');
  779. $prop->setAccessible(true);
  780. $prop->setValue($this, []);
  781. }
  782. public function testStringableClassDoesNotThrow()
  783. {
  784. $mock = $this->getMockBuilder(StringableClass::class)->getMock();
  785. $this->assertInternalType('string', (string) $mock);
  786. }
  787. public function testStringableClassCanBeMocked()
  788. {
  789. $mock = $this->getMockBuilder(StringableClass::class)->getMock();
  790. $mock->method('__toString')->willReturn('foo');
  791. $this->assertSame('foo', (string) $mock);
  792. }
  793. public function traversableProvider()
  794. {
  795. return [
  796. ['Traversable'],
  797. ['\Traversable'],
  798. ['TraversableMockTestInterface'],
  799. [['Traversable']],
  800. [['Iterator','Traversable']],
  801. [['\Iterator','\Traversable']]
  802. ];
  803. }
  804. public function testParameterCallbackConstraintOnlyEvaluatedOnce()
  805. {
  806. $mock = $this->getMockBuilder(Foo::class)->setMethods(['bar'])->getMock();
  807. $expectedNumberOfCalls = 1;
  808. $callCount = 0;
  809. $mock->expects($this->exactly($expectedNumberOfCalls))->method('bar')
  810. ->with($this->callback(function ($argument) use (&$callCount) {
  811. return $argument === 'call_' . $callCount++;
  812. }));
  813. for ($i = 0; $i < $expectedNumberOfCalls; $i++) {
  814. $mock->bar('call_' . $i);
  815. }
  816. }
  817. public function testReturnTypesAreMockedCorrectly()
  818. {
  819. /** @var ClassWithAllPossibleReturnTypes|MockObject $stub */
  820. $stub = $this->createMock(ClassWithAllPossibleReturnTypes::class);
  821. $this->assertNull($stub->methodWithNoReturnTypeDeclaration());
  822. $this->assertSame('', $stub->methodWithStringReturnTypeDeclaration());
  823. $this->assertSame(0.0, $stub->methodWithFloatReturnTypeDeclaration());
  824. $this->assertSame(0, $stub->methodWithIntReturnTypeDeclaration());
  825. $this->assertFalse($stub->methodWithBoolReturnTypeDeclaration());
  826. $this->assertSame([], $stub->methodWithArrayReturnTypeDeclaration());
  827. $this->assertInstanceOf(MockObject::class, $stub->methodWithClassReturnTypeDeclaration());
  828. }
  829. /**
  830. * @requires PHP 7.1
  831. */
  832. public function testVoidReturnTypeIsMockedCorrectly()
  833. {
  834. /** @var ClassWithAllPossibleReturnTypes|MockObject $stub */
  835. $stub = $this->createMock(ClassWithAllPossibleReturnTypes::class);
  836. $this->assertNull($stub->methodWithVoidReturnTypeDeclaration());
  837. }
  838. /**
  839. * @requires PHP 7.2
  840. */
  841. public function testObjectReturnTypeIsMockedCorrectly()
  842. {
  843. /** @var ClassWithAllPossibleReturnTypes|MockObject $stub */
  844. $stub = $this->createMock(ClassWithAllPossibleReturnTypes::class);
  845. $this->assertInstanceOf(stdClass::class, $stub->methodWithObjectReturnTypeDeclaration());
  846. }
  847. }