GeneratorTest.php 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  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\Generator;
  11. use PHPUnit\Framework\MockObject\MockObject;
  12. use PHPUnit\Framework\TestCase;
  13. /**
  14. * @covers \PHPUnit\Framework\MockObject\Generator
  15. *
  16. * @uses \PHPUnit\Framework\MockObject\InvocationMocker
  17. * @uses \PHPUnit\Framework\MockObject\Builder\InvocationMocker
  18. * @uses \PHPUnit\Framework\MockObject\Invocation\ObjectInvocation
  19. * @uses \PHPUnit\Framework\MockObject\Invocation\StaticInvocation
  20. * @uses \PHPUnit\Framework\MockObject\Matcher
  21. * @uses \PHPUnit\Framework\MockObject\Matcher\InvokedRecorder
  22. * @uses \PHPUnit\Framework\MockObject\Matcher\MethodName
  23. * @uses \PHPUnit\Framework\MockObject\Stub\ReturnStub
  24. * @uses \PHPUnit\Framework\MockObject\Matcher\InvokedCount
  25. */
  26. class GeneratorTest extends TestCase
  27. {
  28. /**
  29. * @var Generator
  30. */
  31. private $generator;
  32. protected function setUp()
  33. {
  34. $this->generator = new Generator;
  35. }
  36. public function testGetMockFailsWhenInvalidFunctionNameIsPassedInAsAFunctionToMock()
  37. {
  38. $this->expectException(\PHPUnit\Framework\MockObject\RuntimeException::class);
  39. $this->generator->getMock(stdClass::class, [0]);
  40. }
  41. public function testGetMockCanCreateNonExistingFunctions()
  42. {
  43. $mock = $this->generator->getMock(stdClass::class, ['testFunction']);
  44. $this->assertTrue(method_exists($mock, 'testFunction'));
  45. }
  46. public function testGetMockGeneratorFails()
  47. {
  48. $this->expectException(\PHPUnit\Framework\MockObject\RuntimeException::class);
  49. $this->expectExceptionMessage('duplicates: "foo, bar, foo" (duplicate: "foo")');
  50. $this->generator->getMock(stdClass::class, ['foo', 'bar', 'foo']);
  51. }
  52. /**
  53. * @requires PHP 7
  54. */
  55. public function testGetMockBlacklistedMethodNamesPhp7()
  56. {
  57. $mock = $this->generator->getMock(InterfaceWithSemiReservedMethodName::class);
  58. $this->assertTrue(method_exists($mock, 'unset'));
  59. $this->assertInstanceOf(InterfaceWithSemiReservedMethodName::class, $mock);
  60. }
  61. public function testGetMockForAbstractClassDoesNotFailWhenFakingInterfaces()
  62. {
  63. $mock = $this->generator->getMockForAbstractClass(Countable::class);
  64. $this->assertTrue(method_exists($mock, 'count'));
  65. }
  66. public function testGetMockForAbstractClassStubbingAbstractClass()
  67. {
  68. $mock = $this->generator->getMockForAbstractClass(AbstractMockTestClass::class);
  69. $this->assertTrue(method_exists($mock, 'doSomething'));
  70. }
  71. public function testGetMockForAbstractClassWithNonExistentMethods()
  72. {
  73. $mock = $this->generator->getMockForAbstractClass(
  74. AbstractMockTestClass::class,
  75. [],
  76. '',
  77. true,
  78. true,
  79. true,
  80. ['nonexistentMethod']
  81. );
  82. $this->assertTrue(method_exists($mock, 'nonexistentMethod'));
  83. $this->assertTrue(method_exists($mock, 'doSomething'));
  84. }
  85. public function testGetMockForAbstractClassShouldCreateStubsOnlyForAbstractMethodWhenNoMethodsWereInformed()
  86. {
  87. $mock = $this->generator->getMockForAbstractClass(AbstractMockTestClass::class);
  88. $mock->expects($this->any())
  89. ->method('doSomething')
  90. ->willReturn('testing');
  91. $this->assertEquals('testing', $mock->doSomething());
  92. $this->assertEquals(1, $mock->returnAnything());
  93. }
  94. /**
  95. * @dataProvider getMockForAbstractClassExpectsInvalidArgumentExceptionDataprovider
  96. */
  97. public function testGetMockForAbstractClassExpectingInvalidArgumentException($className, $mockClassName)
  98. {
  99. $this->expectException(PHPUnit\Framework\Exception::class);
  100. $this->generator->getMockForAbstractClass($className, [], $mockClassName);
  101. }
  102. public function testGetMockForAbstractClassAbstractClassDoesNotExist()
  103. {
  104. $this->expectException(\PHPUnit\Framework\MockObject\RuntimeException::class);
  105. $this->generator->getMockForAbstractClass('Tux');
  106. }
  107. public function getMockForAbstractClassExpectsInvalidArgumentExceptionDataprovider()
  108. {
  109. return [
  110. 'className not a string' => [[], ''],
  111. 'mockClassName not a string' => [Countable::class, new stdClass],
  112. ];
  113. }
  114. public function testGetMockForTraitWithNonExistentMethodsAndNonAbstractMethods()
  115. {
  116. $mock = $this->generator->getMockForTrait(
  117. AbstractTrait::class,
  118. [],
  119. '',
  120. true,
  121. true,
  122. true,
  123. ['nonexistentMethod']
  124. );
  125. $this->assertTrue(method_exists($mock, 'nonexistentMethod'));
  126. $this->assertTrue(method_exists($mock, 'doSomething'));
  127. $this->assertTrue($mock->mockableMethod());
  128. $this->assertTrue($mock->anotherMockableMethod());
  129. }
  130. public function testGetMockForTraitStubbingAbstractMethod()
  131. {
  132. $mock = $this->generator->getMockForTrait(AbstractTrait::class);
  133. $this->assertTrue(method_exists($mock, 'doSomething'));
  134. }
  135. public function testGetMockForSingletonWithReflectionSuccess()
  136. {
  137. $mock = $this->generator->getMock(SingletonClass::class, ['doSomething'], [], '', false);
  138. $this->assertInstanceOf('SingletonClass', $mock);
  139. }
  140. public function testExceptionIsRaisedForMutuallyExclusiveOptions()
  141. {
  142. $this->expectException(\PHPUnit\Framework\MockObject\RuntimeException::class);
  143. $this->generator->getMock(stdClass::class, [], [], '', false, true, true, true, true);
  144. }
  145. /**
  146. * @requires PHP 7
  147. */
  148. public function testCanImplementInterfacesThatHaveMethodsWithReturnTypes()
  149. {
  150. $stub = $this->generator->getMock([AnInterfaceWithReturnType::class, AnInterface::class]);
  151. $this->assertInstanceOf(AnInterfaceWithReturnType::class, $stub);
  152. $this->assertInstanceOf(AnInterface::class, $stub);
  153. $this->assertInstanceOf(MockObject::class, $stub);
  154. }
  155. public function testCanConfigureMethodsForDoubleOfNonExistentClass()
  156. {
  157. $className = 'X' . md5(microtime());
  158. $mock = $this->generator->getMock($className, ['someMethod']);
  159. $this->assertInstanceOf($className, $mock);
  160. }
  161. public function testCanInvokeMethodsOfNonExistentClass()
  162. {
  163. $className = 'X' . md5(microtime());
  164. $mock = $this->generator->getMock($className, ['someMethod']);
  165. $mock->expects($this->once())->method('someMethod');
  166. $this->assertNull($mock->someMethod());
  167. }
  168. }