1<?php 2/** 3 * @covers PHPUnit_Framework_MockObject_Generator 4 * 5 * @uses PHPUnit_Framework_MockObject_InvocationMocker 6 * @uses PHPUnit_Framework_MockObject_Builder_InvocationMocker 7 * @uses PHPUnit_Framework_MockObject_Invocation_Object 8 * @uses PHPUnit_Framework_MockObject_Invocation_Static 9 * @uses PHPUnit_Framework_MockObject_Matcher 10 * @uses PHPUnit_Framework_MockObject_Matcher_InvokedRecorder 11 * @uses PHPUnit_Framework_MockObject_Matcher_MethodName 12 * @uses PHPUnit_Framework_MockObject_Stub_Return 13 * @uses PHPUnit_Framework_MockObject_Matcher_InvokedCount 14 */ 15class Framework_MockObject_GeneratorTest extends PHPUnit_Framework_TestCase 16{ 17 /** 18 * @var PHPUnit_Framework_MockObject_Generator 19 */ 20 private $generator; 21 22 protected function setUp() 23 { 24 $this->generator = new PHPUnit_Framework_MockObject_Generator; 25 } 26 27 /** 28 * @expectedException PHPUnit_Framework_MockObject_RuntimeException 29 */ 30 public function testGetMockFailsWhenInvalidFunctionNameIsPassedInAsAFunctionToMock() 31 { 32 $this->generator->getMock(stdClass::class, [0]); 33 } 34 35 public function testGetMockCanCreateNonExistingFunctions() 36 { 37 $mock = $this->generator->getMock(stdClass::class, ['testFunction']); 38 39 $this->assertTrue(method_exists($mock, 'testFunction')); 40 } 41 42 /** 43 * @expectedException PHPUnit_Framework_MockObject_RuntimeException 44 * @expectedExceptionMessage duplicates: "foo, bar, foo" (duplicate: "foo") 45 */ 46 public function testGetMockGeneratorFails() 47 { 48 $this->generator->getMock(stdClass::class, ['foo', 'bar', 'foo']); 49 } 50 51 /** 52 * @requires PHP 7 53 */ 54 public function testGetMockBlacklistedMethodNamesPhp7() 55 { 56 $mock = $this->generator->getMock(InterfaceWithSemiReservedMethodName::class); 57 58 $this->assertTrue(method_exists($mock, 'unset')); 59 $this->assertInstanceOf(InterfaceWithSemiReservedMethodName::class, $mock); 60 } 61 62 public function testGetMockForAbstractClassDoesNotFailWhenFakingInterfaces() 63 { 64 $mock = $this->generator->getMockForAbstractClass(Countable::class); 65 66 $this->assertTrue(method_exists($mock, 'count')); 67 } 68 69 public function testGetMockForAbstractClassStubbingAbstractClass() 70 { 71 $mock = $this->generator->getMockForAbstractClass(AbstractMockTestClass::class); 72 73 $this->assertTrue(method_exists($mock, 'doSomething')); 74 } 75 76 public function testGetMockForAbstractClassWithNonExistentMethods() 77 { 78 $mock = $this->generator->getMockForAbstractClass( 79 AbstractMockTestClass::class, 80 [], 81 '', 82 true, 83 true, 84 true, 85 ['nonexistentMethod'] 86 ); 87 88 $this->assertTrue(method_exists($mock, 'nonexistentMethod')); 89 $this->assertTrue(method_exists($mock, 'doSomething')); 90 } 91 92 public function testGetMockForAbstractClassShouldCreateStubsOnlyForAbstractMethodWhenNoMethodsWereInformed() 93 { 94 $mock = $this->generator->getMockForAbstractClass(AbstractMockTestClass::class); 95 96 $mock->expects($this->any()) 97 ->method('doSomething') 98 ->willReturn('testing'); 99 100 $this->assertEquals('testing', $mock->doSomething()); 101 $this->assertEquals(1, $mock->returnAnything()); 102 } 103 104 /** 105 * @dataProvider getMockForAbstractClassExpectsInvalidArgumentExceptionDataprovider 106 * @expectedException PHPUnit_Framework_Exception 107 */ 108 public function testGetMockForAbstractClassExpectingInvalidArgumentException($className, $mockClassName) 109 { 110 $this->generator->getMockForAbstractClass($className, [], $mockClassName); 111 } 112 113 /** 114 * @expectedException PHPUnit_Framework_MockObject_RuntimeException 115 */ 116 public function testGetMockForAbstractClassAbstractClassDoesNotExist() 117 { 118 $this->generator->getMockForAbstractClass('Tux'); 119 } 120 121 public function getMockForAbstractClassExpectsInvalidArgumentExceptionDataprovider() 122 { 123 return [ 124 'className not a string' => [[], ''], 125 'mockClassName not a string' => [Countable::class, new stdClass], 126 ]; 127 } 128 129 public function testGetMockForTraitWithNonExistentMethodsAndNonAbstractMethods() 130 { 131 $mock = $this->generator->getMockForTrait( 132 AbstractTrait::class, 133 [], 134 '', 135 true, 136 true, 137 true, 138 ['nonexistentMethod'] 139 ); 140 141 $this->assertTrue(method_exists($mock, 'nonexistentMethod')); 142 $this->assertTrue(method_exists($mock, 'doSomething')); 143 $this->assertTrue($mock->mockableMethod()); 144 $this->assertTrue($mock->anotherMockableMethod()); 145 } 146 147 public function testGetMockForTraitStubbingAbstractMethod() 148 { 149 $mock = $this->generator->getMockForTrait(AbstractTrait::class); 150 151 $this->assertTrue(method_exists($mock, 'doSomething')); 152 } 153 154 public function testGetMockForSingletonWithReflectionSuccess() 155 { 156 $mock = $this->generator->getMock(SingletonClass::class, ['doSomething'], [], '', false); 157 158 $this->assertInstanceOf('SingletonClass', $mock); 159 } 160 161 /** 162 * @expectedException PHPUnit_Framework_MockObject_RuntimeException 163 */ 164 public function testExceptionIsRaisedForMutuallyExclusiveOptions() 165 { 166 $this->generator->getMock(stdClass::class, [], [], '', false, true, true, true, true); 167 } 168 169 /** 170 * @requires PHP 7 171 */ 172 public function testCanImplementInterfacesThatHaveMethodsWithReturnTypes() 173 { 174 $stub = $this->generator->getMock([AnInterfaceWithReturnType::class, AnInterface::class]); 175 176 $this->assertInstanceOf(AnInterfaceWithReturnType::class, $stub); 177 $this->assertInstanceOf(AnInterface::class, $stub); 178 $this->assertInstanceOf(PHPUnit_Framework_MockObject_MockObject::class, $stub); 179 } 180 181 public function testCanConfigureMethodsForDoubleOfNonExistentClass() 182 { 183 $className = 'X' . md5(microtime()); 184 185 $mock = $this->generator->getMock($className, ['someMethod']); 186 187 $this->assertInstanceOf($className, $mock); 188 } 189 190 public function testCanInvokeMethodsOfNonExistentClass() 191 { 192 $className = 'X' . md5(microtime()); 193 194 $mock = $this->generator->getMock($className, ['someMethod']); 195 196 $mock->expects($this->once())->method('someMethod'); 197 198 $this->assertNull($mock->someMethod()); 199 } 200} 201