Skip to content

Support PHPUnit 12 by avoiding removed methods getMockForAbstractClass() and addMethods() #75

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Mar 8, 2025
109 changes: 109 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ jobs:
strategy:
matrix:
php-version:
- '8.4'
- '8.3'
- '8.2'
- '8.1'
Expand All @@ -23,6 +24,10 @@ jobs:
- '7.1'
- '7.0'
phpunit-version:
- '12.0.0'
- '11.5.0'
- '11.4.0'
- '11.3.0'
- '11.2.0'
- '11.1.0'
- '11.0.0'
Expand Down Expand Up @@ -58,6 +63,52 @@ jobs:
- '6.0.0'

exclude:
# PHP 8.4 Exclusions
- php-version: '8.4'
phpunit-version: '9.4.0'
- php-version: '8.4'
phpunit-version: '9.3.0'
- php-version: '8.4'
phpunit-version: '9.2.0'
- php-version: '8.4'
phpunit-version: '9.1.0'
- php-version: '8.4'
phpunit-version: '9.0.0'
- php-version: '8.4'
phpunit-version: '8.4.0'
- php-version: '8.4'
phpunit-version: '8.3.0'
- php-version: '8.4'
phpunit-version: '8.2.0'
- php-version: '8.4'
phpunit-version: '8.1.0'
- php-version: '8.4'
phpunit-version: '8.0.0'
- php-version: '8.4'
phpunit-version: '7.5.0'
- php-version: '8.4'
phpunit-version: '7.4.0'
- php-version: '8.4'
phpunit-version: '7.3.0'
- php-version: '8.4'
phpunit-version: '7.2.0'
- php-version: '8.4'
phpunit-version: '7.1.0'
- php-version: '8.4'
phpunit-version: '7.0.0'
- php-version: '8.4'
phpunit-version: '6.5.0'
- php-version: '8.4'
phpunit-version: '6.4.0'
- php-version: '8.4'
phpunit-version: '6.3.0'
- php-version: '8.4'
phpunit-version: '6.2.0'
- php-version: '8.4'
phpunit-version: '6.1.0'
- php-version: '8.4'
phpunit-version: '6.0.0'

# PHP 8.3 Exclusions
- php-version: '8.3'
phpunit-version: '9.4.0'
Expand Down Expand Up @@ -105,6 +156,8 @@ jobs:
phpunit-version: '6.0.0'

# PHP 8.2 Exclusions
- php-version: '8.2'
phpunit-version: '12.0.0'
- php-version: '8.2'
phpunit-version: '9.4.0'
- php-version: '8.2'
Expand Down Expand Up @@ -151,6 +204,14 @@ jobs:
phpunit-version: '6.0.0'

# PHP 8.1 Exclusions
- php-version: '8.1'
phpunit-version: '12.0.0'
- php-version: '8.1'
phpunit-version: '11.5.0'
- php-version: '8.1'
phpunit-version: '11.4.0'
- php-version: '8.1'
phpunit-version: '11.3.0'
- php-version: '8.1'
phpunit-version: '11.2.0'
- php-version: '8.1'
Expand Down Expand Up @@ -203,6 +264,14 @@ jobs:
phpunit-version: '6.0.0'

# PHP 8.0 Exclusions
- php-version: '8.0'
phpunit-version: '12.0.0'
- php-version: '8.0'
phpunit-version: '11.5.0'
- php-version: '8.0'
phpunit-version: '11.4.0'
- php-version: '8.0'
phpunit-version: '11.3.0'
- php-version: '8.0'
phpunit-version: '11.2.0'
- php-version: '8.0'
Expand Down Expand Up @@ -263,6 +332,14 @@ jobs:
phpunit-version: '6.0.0'

# PHP 7.4 Exclusions
- php-version: '7.4'
phpunit-version: '12.0.0'
- php-version: '7.4'
phpunit-version: '11.5.0'
- php-version: '7.4'
phpunit-version: '11.4.0'
- php-version: '7.4'
phpunit-version: '11.3.0'
- php-version: '7.4'
phpunit-version: '11.2.0'
- php-version: '7.4'
Expand Down Expand Up @@ -309,6 +386,14 @@ jobs:
phpunit-version: '6.0.0'

# PHP 7.3 Exclusions
- php-version: '7.3'
phpunit-version: '12.0.0'
- php-version: '7.3'
phpunit-version: '11.5.0'
- php-version: '7.3'
phpunit-version: '11.4.0'
- php-version: '7.3'
phpunit-version: '11.3.0'
- php-version: '7.3'
phpunit-version: '11.2.0'
- php-version: '7.3'
Expand All @@ -329,6 +414,14 @@ jobs:
phpunit-version: '10.0.0'

# PHP 7.2 Exclusions
- php-version: '7.2'
phpunit-version: '12.0.0'
- php-version: '7.2'
phpunit-version: '11.5.0'
- php-version: '7.2'
phpunit-version: '11.4.0'
- php-version: '7.2'
phpunit-version: '11.3.0'
- php-version: '7.2'
phpunit-version: '11.2.0'
- php-version: '7.2'
Expand Down Expand Up @@ -363,6 +456,14 @@ jobs:
phpunit-version: '9.0.0'

# PHP 7.1 Exclusions
- php-version: '7.1'
phpunit-version: '12.0.0'
- php-version: '7.1'
phpunit-version: '11.5.0'
- php-version: '7.1'
phpunit-version: '11.4.0'
- php-version: '7.1'
phpunit-version: '11.3.0'
- php-version: '7.1'
phpunit-version: '11.2.0'
- php-version: '7.1'
Expand Down Expand Up @@ -409,6 +510,14 @@ jobs:
phpunit-version: '8.0.0'

# PHP 7.0 Exclusions
- php-version: '7.0'
phpunit-version: '12.0.0'
- php-version: '7.0'
phpunit-version: '11.5.0'
- php-version: '7.0'
phpunit-version: '11.4.0'
- php-version: '7.0'
phpunit-version: '11.3.0'
- php-version: '7.0'
phpunit-version: '11.2.0'
- php-version: '7.0'
Expand Down
5 changes: 5 additions & 0 deletions autoload.php
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,11 @@ class_alias(
}

if ($hasVersion
&& version_compare(\PHPUnit\Runner\Version::id(), '12.0.0') >= 0
) {
class_alias(\phpmock\phpunit\DefaultArgumentRemoverReturnTypes120::class, \phpmock\phpunit\DefaultArgumentRemover::class);
class_alias(\phpmock\phpunit\MockObjectProxyReturnTypes120::class, \phpmock\phpunit\MockObjectProxy::class);
} elseif ($hasVersion
&& version_compare(\PHPUnit\Runner\Version::id(), '10.0.0') >= 0
) {
class_alias(\phpmock\phpunit\DefaultArgumentRemoverReturnTypes100::class, \phpmock\phpunit\DefaultArgumentRemover::class);
Expand Down
128 changes: 128 additions & 0 deletions classes/DefaultArgumentRemoverReturnTypes120.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
<?php

namespace phpmock\phpunit;

use phpmock\generator\MockFunctionGenerator;
use PHPUnit\Framework\MockObject\Invocation;
use PHPUnit\Framework\MockObject\Rule\InvocationOrder;
use ReflectionClass;

/**
* Removes default arguments from the invocation.
*
* @author Markus Malkusch <[email protected]>
* @link bitcoin:1335STSwu9hST4vcMRppEPgENMHD2r1REK Donations
* @license http://www.wtfpl.net/txt/copying/ WTFPL
* @internal
*/
class DefaultArgumentRemoverReturnTypes120 extends InvocationOrder
{
/**
* @SuppressWarnings(PHPMD)
*/
public function invokedDo(Invocation $invocation): void
{
}

/**
* @SuppressWarnings(PHPMD)
*/
public function matches(Invocation $invocation) : bool
{
$iClass = class_exists(Invocation::class);

if ($iClass
|| $invocation instanceof Invocation\StaticInvocation
) {
$this->removeDefaultArguments(
$invocation,
$iClass ? Invocation::class : Invocation\StaticInvocation::class
);
} elseif (!$this->shouldRemoveDefaultArgumentsWithReflection($invocation)) {
MockFunctionGenerator::removeDefaultArguments($invocation->parameters);
}

return false;
}

public function verify() : void
{
}

/**
* This method is not defined in the interface, but used in
* PHPUnit_Framework_MockObject_InvocationMocker::hasMatchers().
*
* @return boolean
* @see \PHPUnit_Framework_MockObject_InvocationMocker::hasMatchers()
*/
public function hasMatchers()
{
return false;
}

public function toString() : string
{
return __CLASS__;
}

/**
* Remove default arguments from StaticInvocation or its children (hack)
*
* @SuppressWarnings(PHPMD)
*/
private function removeDefaultArguments(Invocation $invocation, string $class)
{
if ($this->shouldRemoveDefaultArgumentsWithReflection($invocation)) {
return;
}

$remover = function () {
MockFunctionGenerator::removeDefaultArguments($this->parameters);
};

$remover->bindTo($invocation, $class)();
}

/**
* Alternative to remove default arguments from StaticInvocation or its children (hack)
*
* @SuppressWarnings(PHPMD.StaticAccess)
*/
public static function removeDefaultArgumentsWithReflection(Invocation $invocation): Invocation
{
if (!(new self())->shouldRemoveDefaultArgumentsWithReflection($invocation)) {
return $invocation;
}

$reflection = new ReflectionClass($invocation);

$reflectionReturnType = $reflection->getProperty('returnType');
$reflectionReturnType->setAccessible(true);

$reflectionIsOptional = $reflection->getProperty('isReturnTypeNullable');
$reflectionIsOptional->setAccessible(true);

$returnType = $reflectionReturnType->getValue($invocation);

if ($reflectionIsOptional->getValue($invocation)) {
$returnType = '?' . $returnType;
}

$parameters = $invocation->parameters();
MockFunctionGenerator::removeDefaultArguments($parameters);

return new Invocation(
$invocation->className(),
$invocation->methodName(),
$parameters,
$returnType,
$invocation->object()
);
}

protected function shouldRemoveDefaultArgumentsWithReflection(Invocation $invocation)
{
return method_exists($invocation, 'parameters');
}
}
Loading