Skip to content

Commit e01b288

Browse files
authored
Support PHPUnit 12 by avoiding removed methods getMockForAbstractClass() and addMethods() (#75)
1 parent c1d0c2f commit e01b288

7 files changed

+354
-7
lines changed

.github/workflows/tests.yml

+109
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ jobs:
1313
strategy:
1414
matrix:
1515
php-version:
16+
- '8.4'
1617
- '8.3'
1718
- '8.2'
1819
- '8.1'
@@ -23,6 +24,10 @@ jobs:
2324
- '7.1'
2425
- '7.0'
2526
phpunit-version:
27+
- '12.0.0'
28+
- '11.5.0'
29+
- '11.4.0'
30+
- '11.3.0'
2631
- '11.2.0'
2732
- '11.1.0'
2833
- '11.0.0'
@@ -58,6 +63,52 @@ jobs:
5863
- '6.0.0'
5964

6065
exclude:
66+
# PHP 8.4 Exclusions
67+
- php-version: '8.4'
68+
phpunit-version: '9.4.0'
69+
- php-version: '8.4'
70+
phpunit-version: '9.3.0'
71+
- php-version: '8.4'
72+
phpunit-version: '9.2.0'
73+
- php-version: '8.4'
74+
phpunit-version: '9.1.0'
75+
- php-version: '8.4'
76+
phpunit-version: '9.0.0'
77+
- php-version: '8.4'
78+
phpunit-version: '8.4.0'
79+
- php-version: '8.4'
80+
phpunit-version: '8.3.0'
81+
- php-version: '8.4'
82+
phpunit-version: '8.2.0'
83+
- php-version: '8.4'
84+
phpunit-version: '8.1.0'
85+
- php-version: '8.4'
86+
phpunit-version: '8.0.0'
87+
- php-version: '8.4'
88+
phpunit-version: '7.5.0'
89+
- php-version: '8.4'
90+
phpunit-version: '7.4.0'
91+
- php-version: '8.4'
92+
phpunit-version: '7.3.0'
93+
- php-version: '8.4'
94+
phpunit-version: '7.2.0'
95+
- php-version: '8.4'
96+
phpunit-version: '7.1.0'
97+
- php-version: '8.4'
98+
phpunit-version: '7.0.0'
99+
- php-version: '8.4'
100+
phpunit-version: '6.5.0'
101+
- php-version: '8.4'
102+
phpunit-version: '6.4.0'
103+
- php-version: '8.4'
104+
phpunit-version: '6.3.0'
105+
- php-version: '8.4'
106+
phpunit-version: '6.2.0'
107+
- php-version: '8.4'
108+
phpunit-version: '6.1.0'
109+
- php-version: '8.4'
110+
phpunit-version: '6.0.0'
111+
61112
# PHP 8.3 Exclusions
62113
- php-version: '8.3'
63114
phpunit-version: '9.4.0'
@@ -105,6 +156,8 @@ jobs:
105156
phpunit-version: '6.0.0'
106157

107158
# PHP 8.2 Exclusions
159+
- php-version: '8.2'
160+
phpunit-version: '12.0.0'
108161
- php-version: '8.2'
109162
phpunit-version: '9.4.0'
110163
- php-version: '8.2'
@@ -151,6 +204,14 @@ jobs:
151204
phpunit-version: '6.0.0'
152205

153206
# PHP 8.1 Exclusions
207+
- php-version: '8.1'
208+
phpunit-version: '12.0.0'
209+
- php-version: '8.1'
210+
phpunit-version: '11.5.0'
211+
- php-version: '8.1'
212+
phpunit-version: '11.4.0'
213+
- php-version: '8.1'
214+
phpunit-version: '11.3.0'
154215
- php-version: '8.1'
155216
phpunit-version: '11.2.0'
156217
- php-version: '8.1'
@@ -203,6 +264,14 @@ jobs:
203264
phpunit-version: '6.0.0'
204265

205266
# PHP 8.0 Exclusions
267+
- php-version: '8.0'
268+
phpunit-version: '12.0.0'
269+
- php-version: '8.0'
270+
phpunit-version: '11.5.0'
271+
- php-version: '8.0'
272+
phpunit-version: '11.4.0'
273+
- php-version: '8.0'
274+
phpunit-version: '11.3.0'
206275
- php-version: '8.0'
207276
phpunit-version: '11.2.0'
208277
- php-version: '8.0'
@@ -263,6 +332,14 @@ jobs:
263332
phpunit-version: '6.0.0'
264333

265334
# PHP 7.4 Exclusions
335+
- php-version: '7.4'
336+
phpunit-version: '12.0.0'
337+
- php-version: '7.4'
338+
phpunit-version: '11.5.0'
339+
- php-version: '7.4'
340+
phpunit-version: '11.4.0'
341+
- php-version: '7.4'
342+
phpunit-version: '11.3.0'
266343
- php-version: '7.4'
267344
phpunit-version: '11.2.0'
268345
- php-version: '7.4'
@@ -309,6 +386,14 @@ jobs:
309386
phpunit-version: '6.0.0'
310387

311388
# PHP 7.3 Exclusions
389+
- php-version: '7.3'
390+
phpunit-version: '12.0.0'
391+
- php-version: '7.3'
392+
phpunit-version: '11.5.0'
393+
- php-version: '7.3'
394+
phpunit-version: '11.4.0'
395+
- php-version: '7.3'
396+
phpunit-version: '11.3.0'
312397
- php-version: '7.3'
313398
phpunit-version: '11.2.0'
314399
- php-version: '7.3'
@@ -329,6 +414,14 @@ jobs:
329414
phpunit-version: '10.0.0'
330415

331416
# PHP 7.2 Exclusions
417+
- php-version: '7.2'
418+
phpunit-version: '12.0.0'
419+
- php-version: '7.2'
420+
phpunit-version: '11.5.0'
421+
- php-version: '7.2'
422+
phpunit-version: '11.4.0'
423+
- php-version: '7.2'
424+
phpunit-version: '11.3.0'
332425
- php-version: '7.2'
333426
phpunit-version: '11.2.0'
334427
- php-version: '7.2'
@@ -363,6 +456,14 @@ jobs:
363456
phpunit-version: '9.0.0'
364457

365458
# PHP 7.1 Exclusions
459+
- php-version: '7.1'
460+
phpunit-version: '12.0.0'
461+
- php-version: '7.1'
462+
phpunit-version: '11.5.0'
463+
- php-version: '7.1'
464+
phpunit-version: '11.4.0'
465+
- php-version: '7.1'
466+
phpunit-version: '11.3.0'
366467
- php-version: '7.1'
367468
phpunit-version: '11.2.0'
368469
- php-version: '7.1'
@@ -409,6 +510,14 @@ jobs:
409510
phpunit-version: '8.0.0'
410511

411512
# PHP 7.0 Exclusions
513+
- php-version: '7.0'
514+
phpunit-version: '12.0.0'
515+
- php-version: '7.0'
516+
phpunit-version: '11.5.0'
517+
- php-version: '7.0'
518+
phpunit-version: '11.4.0'
519+
- php-version: '7.0'
520+
phpunit-version: '11.3.0'
412521
- php-version: '7.0'
413522
phpunit-version: '11.2.0'
414523
- php-version: '7.0'

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 <markus@malkusch.de>
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+
}

0 commit comments

Comments
 (0)