Skip to content

Commit f17d4a9

Browse files
committed
Handle PHPUnit internal changes between version 11 and 12
1 parent 7496e33 commit f17d4a9

5 files changed

+238
-2
lines changed

autoload.php

+5
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,11 @@ class_alias(
9090
}
9191

9292
if ($hasVersion
93+
&& version_compare(\PHPUnit\Runner\Version::id(), '12.0.0') >= 0
94+
) {
95+
class_alias(\phpmock\phpunit\DefaultArgumentRemoverReturnTypes120::class, \phpmock\phpunit\DefaultArgumentRemover::class);
96+
class_alias(\phpmock\phpunit\MockObjectProxyReturnTypes120::class, \phpmock\phpunit\MockObjectProxy::class);
97+
} elseif ($hasVersion
9398
&& version_compare(\PHPUnit\Runner\Version::id(), '10.0.0') >= 0
9499
) {
95100
class_alias(\phpmock\phpunit\DefaultArgumentRemoverReturnTypes100::class, \phpmock\phpunit\DefaultArgumentRemover::class);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
<?php
2+
3+
namespace phpmock\phpunit;
4+
5+
use phpmock\generator\MockFunctionGenerator;
6+
use PHPUnit\Framework\MockObject\Invocation;
7+
use PHPUnit\Framework\MockObject\Rule\InvocationOrder;
8+
use ReflectionClass;
9+
10+
/**
11+
* Removes default arguments from the invocation.
12+
*
13+
* @author Markus Malkusch <[email protected]>
14+
* @link bitcoin:1335STSwu9hST4vcMRppEPgENMHD2r1REK Donations
15+
* @license http://www.wtfpl.net/txt/copying/ WTFPL
16+
* @internal
17+
*/
18+
class DefaultArgumentRemoverReturnTypes120 extends InvocationOrder
19+
{
20+
/**
21+
* @SuppressWarnings(PHPMD)
22+
*/
23+
public function invokedDo(Invocation $invocation): void
24+
{
25+
}
26+
27+
/**
28+
* @SuppressWarnings(PHPMD)
29+
*/
30+
public function matches(Invocation $invocation) : bool
31+
{
32+
$iClass = class_exists(Invocation::class);
33+
34+
if ($iClass
35+
|| $invocation instanceof Invocation\StaticInvocation
36+
) {
37+
$this->removeDefaultArguments(
38+
$invocation,
39+
$iClass ? Invocation::class : Invocation\StaticInvocation::class
40+
);
41+
} elseif (!$this->shouldRemoveDefaultArgumentsWithReflection($invocation)) {
42+
MockFunctionGenerator::removeDefaultArguments($invocation->parameters);
43+
}
44+
45+
return false;
46+
}
47+
48+
public function verify() : void
49+
{
50+
}
51+
52+
/**
53+
* This method is not defined in the interface, but used in
54+
* PHPUnit_Framework_MockObject_InvocationMocker::hasMatchers().
55+
*
56+
* @return boolean
57+
* @see \PHPUnit_Framework_MockObject_InvocationMocker::hasMatchers()
58+
*/
59+
public function hasMatchers()
60+
{
61+
return false;
62+
}
63+
64+
public function toString() : string
65+
{
66+
return __CLASS__;
67+
}
68+
69+
/**
70+
* Remove default arguments from StaticInvocation or its children (hack)
71+
*
72+
* @SuppressWarnings(PHPMD)
73+
*/
74+
private function removeDefaultArguments(Invocation $invocation, string $class)
75+
{
76+
if ($this->shouldRemoveDefaultArgumentsWithReflection($invocation)) {
77+
return;
78+
}
79+
80+
$remover = function () {
81+
MockFunctionGenerator::removeDefaultArguments($this->parameters);
82+
};
83+
84+
$remover->bindTo($invocation, $class)();
85+
}
86+
87+
/**
88+
* Alternative to remove default arguments from StaticInvocation or its children (hack)
89+
*
90+
* @SuppressWarnings(PHPMD.StaticAccess)
91+
*/
92+
public static function removeDefaultArgumentsWithReflection(Invocation $invocation): Invocation
93+
{
94+
if (!(new self())->shouldRemoveDefaultArgumentsWithReflection($invocation)) {
95+
return $invocation;
96+
}
97+
98+
$reflection = new ReflectionClass($invocation);
99+
100+
$reflectionReturnType = $reflection->getProperty('returnType');
101+
$reflectionReturnType->setAccessible(true);
102+
103+
$reflectionIsOptional = $reflection->getProperty('isReturnTypeNullable');
104+
$reflectionIsOptional->setAccessible(true);
105+
106+
$returnType = $reflectionReturnType->getValue($invocation);
107+
108+
if ($reflectionIsOptional->getValue($invocation)) {
109+
$returnType = '?' . $returnType;
110+
}
111+
112+
$parameters = $invocation->parameters();
113+
MockFunctionGenerator::removeDefaultArguments($parameters);
114+
115+
return new Invocation(
116+
$invocation->className(),
117+
$invocation->methodName(),
118+
$parameters,
119+
$returnType,
120+
$invocation->object()
121+
);
122+
}
123+
124+
protected function shouldRemoveDefaultArgumentsWithReflection(Invocation $invocation)
125+
{
126+
return method_exists($invocation, 'parameters');
127+
}
128+
}
+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
<?php
2+
3+
namespace phpmock\phpunit;
4+
5+
use phpmock\integration\MockDelegateFunctionBuilder;
6+
use PHPUnit\Framework\Constraint\Constraint;
7+
use PHPUnit\Framework\MockObject\Builder\InvocationMocker as BuilderInvocationMocker;
8+
use PHPUnit\Framework\MockObject\Builder\InvocationStubber;
9+
use PHPUnit\Framework\MockObject\InvocationHandler;
10+
use PHPUnit\Framework\MockObject\MockObject;
11+
use PHPUnit\Framework\MockObject\Rule\InvocationOrder;
12+
use PHPUnit\Framework\MockObject\Runtime\PropertyHook;
13+
14+
/**
15+
* Proxy for PHPUnit's PHPUnit_Framework_MockObject_MockObject.
16+
*
17+
* @author Markus Malkusch <[email protected]>
18+
* @link bitcoin:1335STSwu9hST4vcMRppEPgENMHD2r1REK Donations
19+
* @license http://www.wtfpl.net/txt/copying/ WTFPL
20+
* @internal
21+
*/
22+
class MockObjectProxyReturnTypes120 implements MockObject
23+
{
24+
/**
25+
* @var MockObject $mockObject The mock object.
26+
*/
27+
private $mockObject;
28+
29+
/**
30+
* Inject the subject.
31+
*
32+
* @param MockObject $mockObject The subject.
33+
*/
34+
public function __construct(MockObject $mockObject)
35+
{
36+
$this->mockObject = $mockObject;
37+
}
38+
39+
/**
40+
* @SuppressWarnings(PHPMD)
41+
*/
42+
// @codingStandardsIgnoreStart
43+
public function __phpunit_getInvocationHandler(): InvocationHandler
44+
{
45+
return $this->mockObject->__phpunit_getInvocationHandler();
46+
}
47+
48+
/**
49+
* @SuppressWarnings(PHPMD)
50+
*/
51+
// @codingStandardsIgnoreStart
52+
public function __phpunit_setOriginalObject(object $originalObject) : void
53+
{
54+
// @codingStandardsIgnoreEnd
55+
$this->mockObject->__phpunit_setOriginalObject($originalObject);
56+
}
57+
58+
/**
59+
* @SuppressWarnings(PHPMD)
60+
*/
61+
// @codingStandardsIgnoreStart
62+
public function __phpunit_verify(bool $unsetInvocationMocker = true) : void
63+
{
64+
// @codingStandardsIgnoreEnd
65+
$this->mockObject->__phpunit_verify($unsetInvocationMocker);
66+
}
67+
68+
public function expects(InvocationOrder $matcher) : BuilderInvocationMocker
69+
{
70+
return $this->mockObject->expects($matcher)->method(MockDelegateFunctionBuilder::METHOD);
71+
}
72+
73+
public function method(Constraint|PropertyHook|string $constraint): InvocationStubber
74+
{
75+
return $this->mockObject->method($constraint);
76+
}
77+
78+
/**
79+
* This method is not part of the contract but was found in
80+
* PHPUnit's mocked_class.tpl.dist.
81+
*
82+
* @SuppressWarnings(PHPMD)
83+
*/
84+
// @codingStandardsIgnoreStart
85+
public function __phpunit_hasMatchers() : bool
86+
{
87+
// @codingStandardsIgnoreEnd
88+
return $this->mockObject->__phpunit_hasMatchers();
89+
}
90+
91+
/**
92+
* @SuppressWarnings(PHPMD)
93+
*/
94+
// @codingStandardsIgnoreStart
95+
public function __phpunit_setReturnValueGeneration(bool $returnValueGeneration) : void
96+
{
97+
// @codingStandardsIgnoreEnd
98+
$this->mockObject->__phpunit_setReturnValueGeneration($returnValueGeneration);
99+
}
100+
}

classes/PHPMock.php

+3-2
Original file line numberDiff line numberDiff line change
@@ -199,8 +199,9 @@ private function prepareCustomTemplates()
199199
}
200200

201201
$mockMethodClasses = [
202-
'PHPUnit\\Framework\\MockObject\\Generator\\MockMethod',
203-
'PHPUnit\\Framework\\MockObject\\MockMethod',
202+
'PHPUnit\\Framework\\MockObject\\Generator\\DoubledMethod', // PHPUnit 12
203+
'PHPUnit\\Framework\\MockObject\\Generator\\MockMethod', // PHPUnit 10-11
204+
'PHPUnit\\Framework\\MockObject\\MockMethod', // PHPUnit 9
204205
];
205206

206207
foreach ($mockMethodClasses as $mockMethodClass) {

tests/MockObjectProxyTest.php

+2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use Mockery;
66
use phpmock\integration\MockDelegateFunctionBuilder;
7+
use PHPUnit\Framework\Attributes\DataProvider;
78
use PHPUnit\Framework\MockObject\Builder\InvocationMocker;
89
use PHPUnit\Framework\MockObject\ConfigurableMethod;
910
use PHPUnit\Framework\MockObject\InvocationHandler;
@@ -137,6 +138,7 @@ public function testHasMatcher()
137138
* @test
138139
* @dataProvider provideTestProxiedMethods
139140
*/
141+
#[DataProvider('provideTestProxiedMethods')]
140142
public function testProxiedMethods($method, array $arguments = [], $expected = null)
141143
{
142144
$mock = Mockery::mock(MockObject::class);

0 commit comments

Comments
 (0)