Chris@0: Chris@14: * Chris@14: * For the full copyright and license information, please view the LICENSE Chris@14: * file that was distributed with this source code. Chris@14: */ Chris@14: Chris@14: use PHPUnit\Framework\MockObject\Generator; Chris@14: use PHPUnit\Framework\MockObject\MockObject; Chris@14: use PHPUnit\Framework\TestCase; Chris@14: Chris@14: /** Chris@14: * @covers \PHPUnit\Framework\MockObject\Generator Chris@14: * Chris@14: * @uses \PHPUnit\Framework\MockObject\InvocationMocker Chris@14: * @uses \PHPUnit\Framework\MockObject\Builder\InvocationMocker Chris@14: * @uses \PHPUnit\Framework\MockObject\Invocation\ObjectInvocation Chris@14: * @uses \PHPUnit\Framework\MockObject\Invocation\StaticInvocation Chris@14: * @uses \PHPUnit\Framework\MockObject\Matcher Chris@14: * @uses \PHPUnit\Framework\MockObject\Matcher\InvokedRecorder Chris@14: * @uses \PHPUnit\Framework\MockObject\Matcher\MethodName Chris@14: * @uses \PHPUnit\Framework\MockObject\Stub\ReturnStub Chris@14: * @uses \PHPUnit\Framework\MockObject\Matcher\InvokedCount Chris@14: */ Chris@14: class GeneratorTest extends TestCase Chris@0: { Chris@0: /** Chris@14: * @var Generator Chris@0: */ Chris@14: private $generator; Chris@0: Chris@0: protected function setUp() Chris@0: { Chris@14: $this->generator = new Generator; Chris@14: } Chris@14: Chris@14: public function testGetMockFailsWhenInvalidFunctionNameIsPassedInAsAFunctionToMock() Chris@14: { Chris@14: $this->expectException(\PHPUnit\Framework\MockObject\RuntimeException::class); Chris@14: Chris@14: $this->generator->getMock(stdClass::class, [0]); Chris@14: } Chris@14: Chris@14: public function testGetMockCanCreateNonExistingFunctions() Chris@14: { Chris@14: $mock = $this->generator->getMock(stdClass::class, ['testFunction']); Chris@14: Chris@14: $this->assertTrue(method_exists($mock, 'testFunction')); Chris@14: } Chris@14: Chris@14: public function testGetMockGeneratorFails() Chris@14: { Chris@14: $this->expectException(\PHPUnit\Framework\MockObject\RuntimeException::class); Chris@14: $this->expectExceptionMessage('duplicates: "foo, bar, foo" (duplicate: "foo")'); Chris@14: Chris@14: $this->generator->getMock(stdClass::class, ['foo', 'bar', 'foo']); Chris@0: } Chris@0: Chris@0: /** Chris@14: * @requires PHP 7 Chris@0: */ Chris@14: public function testGetMockBlacklistedMethodNamesPhp7() Chris@0: { Chris@14: $mock = $this->generator->getMock(InterfaceWithSemiReservedMethodName::class); Chris@14: Chris@14: $this->assertTrue(method_exists($mock, 'unset')); Chris@14: $this->assertInstanceOf(InterfaceWithSemiReservedMethodName::class, $mock); Chris@0: } Chris@0: Chris@0: public function testGetMockForAbstractClassDoesNotFailWhenFakingInterfaces() Chris@0: { Chris@14: $mock = $this->generator->getMockForAbstractClass(Countable::class); Chris@14: Chris@0: $this->assertTrue(method_exists($mock, 'count')); Chris@0: } Chris@0: Chris@0: public function testGetMockForAbstractClassStubbingAbstractClass() Chris@0: { Chris@14: $mock = $this->generator->getMockForAbstractClass(AbstractMockTestClass::class); Chris@14: Chris@0: $this->assertTrue(method_exists($mock, 'doSomething')); Chris@0: } Chris@0: Chris@0: public function testGetMockForAbstractClassWithNonExistentMethods() Chris@0: { Chris@0: $mock = $this->generator->getMockForAbstractClass( Chris@14: AbstractMockTestClass::class, Chris@14: [], Chris@0: '', Chris@0: true, Chris@0: true, Chris@0: true, Chris@14: ['nonexistentMethod'] Chris@0: ); Chris@0: Chris@0: $this->assertTrue(method_exists($mock, 'nonexistentMethod')); Chris@0: $this->assertTrue(method_exists($mock, 'doSomething')); Chris@0: } Chris@0: Chris@0: public function testGetMockForAbstractClassShouldCreateStubsOnlyForAbstractMethodWhenNoMethodsWereInformed() Chris@0: { Chris@14: $mock = $this->generator->getMockForAbstractClass(AbstractMockTestClass::class); Chris@0: Chris@0: $mock->expects($this->any()) Chris@0: ->method('doSomething') Chris@0: ->willReturn('testing'); Chris@0: Chris@0: $this->assertEquals('testing', $mock->doSomething()); Chris@0: $this->assertEquals(1, $mock->returnAnything()); Chris@0: } Chris@0: Chris@0: /** Chris@0: * @dataProvider getMockForAbstractClassExpectsInvalidArgumentExceptionDataprovider Chris@0: */ Chris@0: public function testGetMockForAbstractClassExpectingInvalidArgumentException($className, $mockClassName) Chris@0: { Chris@14: $this->expectException(PHPUnit\Framework\Exception::class); Chris@14: Chris@14: $this->generator->getMockForAbstractClass($className, [], $mockClassName); Chris@0: } Chris@0: Chris@0: public function testGetMockForAbstractClassAbstractClassDoesNotExist() Chris@0: { Chris@14: $this->expectException(\PHPUnit\Framework\MockObject\RuntimeException::class); Chris@14: Chris@14: $this->generator->getMockForAbstractClass('Tux'); Chris@0: } Chris@0: Chris@14: public function getMockForAbstractClassExpectsInvalidArgumentExceptionDataprovider() Chris@0: { Chris@14: return [ Chris@14: 'className not a string' => [[], ''], Chris@14: 'mockClassName not a string' => [Countable::class, new stdClass], Chris@14: ]; Chris@0: } Chris@0: Chris@0: public function testGetMockForTraitWithNonExistentMethodsAndNonAbstractMethods() Chris@0: { Chris@0: $mock = $this->generator->getMockForTrait( Chris@14: AbstractTrait::class, Chris@14: [], Chris@0: '', Chris@0: true, Chris@0: true, Chris@0: true, Chris@14: ['nonexistentMethod'] Chris@0: ); Chris@0: Chris@0: $this->assertTrue(method_exists($mock, 'nonexistentMethod')); Chris@0: $this->assertTrue(method_exists($mock, 'doSomething')); Chris@0: $this->assertTrue($mock->mockableMethod()); Chris@0: $this->assertTrue($mock->anotherMockableMethod()); Chris@0: } Chris@0: Chris@0: public function testGetMockForTraitStubbingAbstractMethod() Chris@0: { Chris@14: $mock = $this->generator->getMockForTrait(AbstractTrait::class); Chris@14: Chris@0: $this->assertTrue(method_exists($mock, 'doSomething')); Chris@0: } Chris@0: Chris@0: public function testGetMockForSingletonWithReflectionSuccess() Chris@0: { Chris@14: $mock = $this->generator->getMock(SingletonClass::class, ['doSomething'], [], '', false); Chris@0: Chris@0: $this->assertInstanceOf('SingletonClass', $mock); Chris@0: } Chris@0: Chris@14: public function testExceptionIsRaisedForMutuallyExclusiveOptions() Chris@0: { Chris@14: $this->expectException(\PHPUnit\Framework\MockObject\RuntimeException::class); Chris@0: Chris@14: $this->generator->getMock(stdClass::class, [], [], '', false, true, true, true, true); Chris@0: } Chris@0: Chris@0: /** Chris@14: * @requires PHP 7 Chris@0: */ Chris@14: public function testCanImplementInterfacesThatHaveMethodsWithReturnTypes() Chris@0: { Chris@14: $stub = $this->generator->getMock([AnInterfaceWithReturnType::class, AnInterface::class]); Chris@0: Chris@14: $this->assertInstanceOf(AnInterfaceWithReturnType::class, $stub); Chris@14: $this->assertInstanceOf(AnInterface::class, $stub); Chris@14: $this->assertInstanceOf(MockObject::class, $stub); Chris@14: } Chris@14: Chris@14: public function testCanConfigureMethodsForDoubleOfNonExistentClass() Chris@14: { Chris@14: $className = 'X' . md5(microtime()); Chris@14: Chris@14: $mock = $this->generator->getMock($className, ['someMethod']); Chris@14: Chris@14: $this->assertInstanceOf($className, $mock); Chris@14: } Chris@14: Chris@14: public function testCanInvokeMethodsOfNonExistentClass() Chris@14: { Chris@14: $className = 'X' . md5(microtime()); Chris@14: Chris@14: $mock = $this->generator->getMock($className, ['someMethod']); Chris@14: Chris@14: $mock->expects($this->once())->method('someMethod'); Chris@14: Chris@14: $this->assertNull($mock->someMethod()); Chris@0: } Chris@0: }