From 81b7b0e5fdd600ac6ef57a90045923be10d90fb9 Mon Sep 17 00:00:00 2001 From: Sebastian Bergmann Date: Wed, 4 Dec 2019 17:00:24 +0100 Subject: [PATCH] Closes #3967 --- ChangeLog-7.5.md | 7 ++ src/Framework/MockObject/Generator.php | 18 +-- .../mock-objects/generator/3967.phpt | 103 ++++++++++++++++++ 3 files changed, 120 insertions(+), 8 deletions(-) create mode 100644 tests/end-to-end/mock-objects/generator/3967.phpt diff --git a/ChangeLog-7.5.md b/ChangeLog-7.5.md index 987df778d54..b63c4152492 100644 --- a/ChangeLog-7.5.md +++ b/ChangeLog-7.5.md @@ -2,6 +2,12 @@ All notable changes of the PHPUnit 7.5 release series are documented in this file using the [Keep a CHANGELOG](https://keepachangelog.com/) principles. +## [7.5.18] - 2019-MM-DD + +### Fixed + +* Fixed [#3967](https://github.com/sebastianbergmann/phpunit/issues/3967): Cannot double interface that extends interface that extends `\Throwable` + ## [7.5.17] - 2019-10-28 ### Fixed @@ -152,6 +158,7 @@ All notable changes of the PHPUnit 7.5 release series are documented in this fil * Fixed [#3429](https://github.com/sebastianbergmann/phpunit/pull/3429): Inefficient loop in `getHookMethods()` * Fixed [#3437](https://github.com/sebastianbergmann/phpunit/pull/3437): JUnit logger skips PHPT tests +[7.5.18]: https://github.com/sebastianbergmann/phpunit/compare/7.5.17...7.5 [7.5.17]: https://github.com/sebastianbergmann/phpunit/compare/7.5.16...7.5.17 [7.5.16]: https://github.com/sebastianbergmann/phpunit/compare/7.5.15...7.5.16 [7.5.15]: https://github.com/sebastianbergmann/phpunit/compare/7.5.14...7.5.15 diff --git a/src/Framework/MockObject/Generator.php b/src/Framework/MockObject/Generator.php index c7300f761b1..9ead92a2687 100644 --- a/src/Framework/MockObject/Generator.php +++ b/src/Framework/MockObject/Generator.php @@ -567,15 +567,17 @@ public function mockClassMethods(string $className, bool $callOriginalMethods, b * * @return \ReflectionMethod[] */ - private function getInterfaceOwnMethods(string $interfaceName): array + private function userDefinedInterfaceMethods(string $interfaceName): array { - $reflect = new ReflectionClass($interfaceName); - $methods = []; + $interface = new ReflectionClass($interfaceName); + $methods = []; - foreach ($reflect->getMethods() as $method) { - if ($method->getDeclaringClass()->getName() === $interfaceName) { - $methods[] = $method; + foreach ($interface->getMethods() as $method) { + if (!$method->isUserDefined()) { + continue; } + + $methods[] = $method; } return $methods; @@ -766,7 +768,7 @@ private function generateMock($type, $explicitMethods, $mockClassName, $callOrig ); } - foreach ($this->getInterfaceOwnMethods($mockClassName['fullClassName']) as $method) { + foreach ($this->userDefinedInterfaceMethods($mockClassName['fullClassName']) as $method) { $methodName = $method->getName(); if ($class->hasMethod($methodName)) { @@ -792,7 +794,7 @@ private function generateMock($type, $explicitMethods, $mockClassName, $callOrig $mockClassName = $this->generateClassName( $actualClassName, - '', + $mockClassName['className'], 'Mock_' ); } diff --git a/tests/end-to-end/mock-objects/generator/3967.phpt b/tests/end-to-end/mock-objects/generator/3967.phpt new file mode 100644 index 00000000000..9572dace1f5 --- /dev/null +++ b/tests/end-to-end/mock-objects/generator/3967.phpt @@ -0,0 +1,103 @@ +--TEST-- +https://github.com/sebastianbergmann/phpunit/issues/3967 +--FILE-- +generate( + 'Baz', + [], + 'MockBaz', + true, + true +); + +print $mock['code']; +--EXPECT-- +class MockBaz extends Exception implements Baz, PHPUnit\Framework\MockObject\MockObject +{ + private $__phpunit_invocationMocker; + private $__phpunit_originalObject; + private $__phpunit_configurable = ['foo']; + private $__phpunit_returnValueGeneration = true; + + + public function foo(): string + { + $__phpunit_arguments = []; + $__phpunit_count = func_num_args(); + + if ($__phpunit_count > 0) { + $__phpunit_arguments_tmp = func_get_args(); + + for ($__phpunit_i = 0; $__phpunit_i < $__phpunit_count; $__phpunit_i++) { + $__phpunit_arguments[] = $__phpunit_arguments_tmp[$__phpunit_i]; + } + } + + $__phpunit_result = $this->__phpunit_getInvocationMocker()->invoke( + new \PHPUnit\Framework\MockObject\Invocation\ObjectInvocation( + 'Bar', 'foo', $__phpunit_arguments, 'string', $this, true + ) + ); + + return $__phpunit_result; + } + + public function expects(\PHPUnit\Framework\MockObject\Matcher\Invocation $matcher) + { + return $this->__phpunit_getInvocationMocker()->expects($matcher); + } + + public function method() + { + $any = new \PHPUnit\Framework\MockObject\Matcher\AnyInvokedCount; + $expects = $this->expects($any); + + return call_user_func_array([$expects, 'method'], func_get_args()); + } + + public function __phpunit_setOriginalObject($originalObject) + { + $this->__phpunit_originalObject = $originalObject; + } + + public function __phpunit_setReturnValueGeneration(bool $returnValueGeneration) + { + $this->__phpunit_returnValueGeneration = $returnValueGeneration; + } + + public function __phpunit_getInvocationMocker() + { + if ($this->__phpunit_invocationMocker === null) { + $this->__phpunit_invocationMocker = new \PHPUnit\Framework\MockObject\InvocationMocker($this->__phpunit_configurable, $this->__phpunit_returnValueGeneration); + } + + return $this->__phpunit_invocationMocker; + } + + public function __phpunit_hasMatchers() + { + return $this->__phpunit_getInvocationMocker()->hasMatchers(); + } + + public function __phpunit_verify(bool $unsetInvocationMocker = true) + { + $this->__phpunit_getInvocationMocker()->verify(); + + if ($unsetInvocationMocker) { + $this->__phpunit_invocationMocker = null; + } + } +}