From a8c81f22e712d7e8da4a794e6411dcf0877549dc Mon Sep 17 00:00:00 2001 From: Fabian Becker Date: Wed, 17 Aug 2016 10:45:22 +0200 Subject: [PATCH 1/3] Fix mocking of interfaces with return types --- src/Framework/MockObject/Generator.php | 39 +++++++++++++------- tests/GeneratorTest.php | 8 ++++ tests/_fixture/AnInterfaceWithReturnType.php | 5 +++ 3 files changed, 38 insertions(+), 14 deletions(-) create mode 100644 tests/_fixture/AnInterfaceWithReturnType.php diff --git a/src/Framework/MockObject/Generator.php b/src/Framework/MockObject/Generator.php index 5686323a..cff41fda 100644 --- a/src/Framework/MockObject/Generator.php +++ b/src/Framework/MockObject/Generator.php @@ -686,20 +686,15 @@ public function generateClassFromWsdl($wsdlFile, $className, array $methods = [] */ private function generateMock($type, $methods, $mockClassName, $callOriginalClone, $callAutoload, $cloneArguments, $callOriginalMethods) { - $templateDir = __DIR__ . DIRECTORY_SEPARATOR . 'Generator' . DIRECTORY_SEPARATOR; - $classTemplate = $this->getTemplate($templateDir . 'mocked_class.tpl'); + $methodReflections = []; + $templateDir = __DIR__ . DIRECTORY_SEPARATOR . 'Generator' . DIRECTORY_SEPARATOR; + $classTemplate = $this->getTemplate($templateDir . 'mocked_class.tpl'); $additionalInterfaces = []; $cloneTemplate = ''; $isClass = false; $isInterface = false; - $mockClassName = $this->generateClassName( - $type, - $mockClassName, - 'Mock_' - ); - if (is_array($type)) { foreach ($type as $_type) { if (!interface_exists($_type, $callAutoload)) { @@ -713,6 +708,13 @@ private function generateMock($type, $methods, $mockClassName, $callOriginalClon $additionalInterfaces[] = $_type; + $typeClass = new ReflectionClass($this->generateClassName( + $_type, + $mockClassName, + 'Mock_' + )['fullClassName'] + ); + foreach ($this->getClassMethods($_type) as $method) { if (in_array($method, $methods)) { throw new PHPUnit_Framework_MockObject_RuntimeException( @@ -723,11 +725,18 @@ private function generateMock($type, $methods, $mockClassName, $callOriginalClon ); } + $methodReflections[$method] = $typeClass->getMethod($method); $methods[] = $method; } } } + $mockClassName = $this->generateClassName( + $type, + $mockClassName, + 'Mock_' + ); + if (class_exists($mockClassName['fullClassName'], $callAutoload)) { $isClass = true; } elseif (interface_exists($mockClassName['fullClassName'], $callAutoload)) { @@ -827,12 +836,14 @@ private function generateMock($type, $methods, $mockClassName, $callOriginalClon } } else { foreach ($methods as $methodName) { - $mockedMethods .= $this->generateMockedMethodDefinition( - $templateDir, - $mockClassName['fullClassName'], - $methodName, - $cloneArguments - ); + if ($this->canMockMethod($methodReflections[$methodName])) { + $mockedMethods .= $this->generateMockedMethodDefinitionFromExisting( + $templateDir, + $methodReflections[$methodName], + $cloneArguments, + $callOriginalMethods + ); + } } } diff --git a/tests/GeneratorTest.php b/tests/GeneratorTest.php index 2cb1f961..d4447061 100644 --- a/tests/GeneratorTest.php +++ b/tests/GeneratorTest.php @@ -180,4 +180,12 @@ public function testExceptionIsRaisedForMutuallyExclusiveOptions() { $this->generator->getMock(stdClass::class, [], [], '', false, true, true, true, true); } + + /** + * @covers PHPUnit_Framework_MockObject_Generator::getMock + */ + public function testCanImplementInterfacesThatHaveMethodsWithReturnTypes() + { + $this->generator->getMock([AnInterfaceWithReturnType::class, AnInterface::class]); + } } diff --git a/tests/_fixture/AnInterfaceWithReturnType.php b/tests/_fixture/AnInterfaceWithReturnType.php new file mode 100644 index 00000000..150857d3 --- /dev/null +++ b/tests/_fixture/AnInterfaceWithReturnType.php @@ -0,0 +1,5 @@ + Date: Wed, 17 Aug 2016 10:45:43 +0200 Subject: [PATCH 2/3] Code style --- src/Framework/MockObject/Generator.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Framework/MockObject/Generator.php b/src/Framework/MockObject/Generator.php index cff41fda..04744466 100644 --- a/src/Framework/MockObject/Generator.php +++ b/src/Framework/MockObject/Generator.php @@ -707,8 +707,7 @@ private function generateMock($type, $methods, $mockClassName, $callOriginalClon } $additionalInterfaces[] = $_type; - - $typeClass = new ReflectionClass($this->generateClassName( + $typeClass = new ReflectionClass($this->generateClassName( $_type, $mockClassName, 'Mock_' @@ -726,7 +725,7 @@ private function generateMock($type, $methods, $mockClassName, $callOriginalClon } $methodReflections[$method] = $typeClass->getMethod($method); - $methods[] = $method; + $methods[] = $method; } } } From a32f84ddb89697162cc2498a99d3af42571d2413 Mon Sep 17 00:00:00 2001 From: Fabian Becker Date: Wed, 17 Aug 2016 11:27:36 +0200 Subject: [PATCH 3/3] Do not execute test in PHP before 7 --- tests/GeneratorTest.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/GeneratorTest.php b/tests/GeneratorTest.php index d4447061..64f7bc8d 100644 --- a/tests/GeneratorTest.php +++ b/tests/GeneratorTest.php @@ -186,6 +186,10 @@ public function testExceptionIsRaisedForMutuallyExclusiveOptions() */ public function testCanImplementInterfacesThatHaveMethodsWithReturnTypes() { + if (PHP_MAJOR_VERSION < 7) { + $this->markTestSkipped('Code fails in PHP < 7.0'); + } + $this->generator->getMock([AnInterfaceWithReturnType::class, AnInterface::class]); } }