From 35832e5a77dfea15a6e17e7483e9f8a1d223f62d Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Mon, 26 Jan 2026 12:17:11 +0100 Subject: [PATCH] [PHPUnit 12] Add CreateStubOverCreateMockArgRector --- config/sets/phpunit120.php | 9 +- .../CreateStubOverCreateMockArgRectorTest.php | 28 +++++ .../Fixture/handle_static_call.php.inc | 37 ++++++ .../Fixture/some_file_with_mocks.php.inc | 41 +++++++ .../config/configured_rule.php | 9 ++ .../Fixture/skip_abstract_method.php.inc | 2 +- ..._to_perform_assertions_method_call.php.inc | 2 +- .../Fixture/skip_mock_expectations.php.inc | 2 +- .../CreateStubOverCreateMockArgRector.php | 112 ++++++++++++++++++ 9 files changed, 238 insertions(+), 4 deletions(-) create mode 100644 rules-tests/PHPUnit120/Rector/CallLike/CreateStubOverCreateMockArgRector/CreateStubOverCreateMockArgRectorTest.php create mode 100644 rules-tests/PHPUnit120/Rector/CallLike/CreateStubOverCreateMockArgRector/Fixture/handle_static_call.php.inc create mode 100644 rules-tests/PHPUnit120/Rector/CallLike/CreateStubOverCreateMockArgRector/Fixture/some_file_with_mocks.php.inc create mode 100644 rules-tests/PHPUnit120/Rector/CallLike/CreateStubOverCreateMockArgRector/config/configured_rule.php create mode 100644 rules/PHPUnit120/Rector/CallLike/CreateStubOverCreateMockArgRector.php diff --git a/config/sets/phpunit120.php b/config/sets/phpunit120.php index 66211939..611a42b8 100644 --- a/config/sets/phpunit120.php +++ b/config/sets/phpunit120.php @@ -3,9 +3,16 @@ declare(strict_types=1); use Rector\Config\RectorConfig; +use Rector\PHPUnit\PHPUnit120\Rector\CallLike\CreateStubOverCreateMockArgRector; use Rector\PHPUnit\PHPUnit120\Rector\Class_\AssertIsTypeMethodCallRector; use Rector\PHPUnit\PHPUnit120\Rector\Class_\RemoveOverrideFinalConstructTestCaseRector; return static function (RectorConfig $rectorConfig): void { - $rectorConfig->rules([RemoveOverrideFinalConstructTestCaseRector::class, AssertIsTypeMethodCallRector::class]); + $rectorConfig->rules([ + RemoveOverrideFinalConstructTestCaseRector::class, + AssertIsTypeMethodCallRector::class, + + // stubs over mocks + CreateStubOverCreateMockArgRector::class, + ]); }; diff --git a/rules-tests/PHPUnit120/Rector/CallLike/CreateStubOverCreateMockArgRector/CreateStubOverCreateMockArgRectorTest.php b/rules-tests/PHPUnit120/Rector/CallLike/CreateStubOverCreateMockArgRector/CreateStubOverCreateMockArgRectorTest.php new file mode 100644 index 00000000..d8d60003 --- /dev/null +++ b/rules-tests/PHPUnit120/Rector/CallLike/CreateStubOverCreateMockArgRector/CreateStubOverCreateMockArgRectorTest.php @@ -0,0 +1,28 @@ +doTestFile($filePath); + } + + public static function provideData(): Iterator + { + return self::yieldFilesFromDirectory(__DIR__ . '/Fixture'); + } + + public function provideConfigFilePath(): string + { + return __DIR__ . '/config/configured_rule.php'; + } +} diff --git a/rules-tests/PHPUnit120/Rector/CallLike/CreateStubOverCreateMockArgRector/Fixture/handle_static_call.php.inc b/rules-tests/PHPUnit120/Rector/CallLike/CreateStubOverCreateMockArgRector/Fixture/handle_static_call.php.inc new file mode 100644 index 00000000..8fe711e4 --- /dev/null +++ b/rules-tests/PHPUnit120/Rector/CallLike/CreateStubOverCreateMockArgRector/Fixture/handle_static_call.php.inc @@ -0,0 +1,37 @@ +createMock(\stdClass::class), + ); + } +} + +?> +----- +createStub(\stdClass::class), + ); + } +} + +?> diff --git a/rules-tests/PHPUnit120/Rector/CallLike/CreateStubOverCreateMockArgRector/Fixture/some_file_with_mocks.php.inc b/rules-tests/PHPUnit120/Rector/CallLike/CreateStubOverCreateMockArgRector/Fixture/some_file_with_mocks.php.inc new file mode 100644 index 00000000..b2708072 --- /dev/null +++ b/rules-tests/PHPUnit120/Rector/CallLike/CreateStubOverCreateMockArgRector/Fixture/some_file_with_mocks.php.inc @@ -0,0 +1,41 @@ +run( + $this->createMock(\stdClass::class), + $this->createMock(\stdClass::class) + ); + } +} + +?> +----- +run( + $this->createStub(\stdClass::class), + $this->createStub(\stdClass::class) + ); + } +} + +?> diff --git a/rules-tests/PHPUnit120/Rector/CallLike/CreateStubOverCreateMockArgRector/config/configured_rule.php b/rules-tests/PHPUnit120/Rector/CallLike/CreateStubOverCreateMockArgRector/config/configured_rule.php new file mode 100644 index 00000000..feb58790 --- /dev/null +++ b/rules-tests/PHPUnit120/Rector/CallLike/CreateStubOverCreateMockArgRector/config/configured_rule.php @@ -0,0 +1,9 @@ +withRules([CreateStubOverCreateMockArgRector::class]); diff --git a/rules-tests/PHPUnit60/Rector/ClassMethod/AddDoesNotPerformAssertionToNonAssertingTestRector/Fixture/skip_abstract_method.php.inc b/rules-tests/PHPUnit60/Rector/ClassMethod/AddDoesNotPerformAssertionToNonAssertingTestRector/Fixture/skip_abstract_method.php.inc index 7cab4c04..4654e7c6 100644 --- a/rules-tests/PHPUnit60/Rector/ClassMethod/AddDoesNotPerformAssertionToNonAssertingTestRector/Fixture/skip_abstract_method.php.inc +++ b/rules-tests/PHPUnit60/Rector/ClassMethod/AddDoesNotPerformAssertionToNonAssertingTestRector/Fixture/skip_abstract_method.php.inc @@ -1,6 +1,6 @@ someMethod($this->createMock(SomeClass::class)); + } + + private function someMethod($someClass) + { + } +} +CODE_SAMPLE + , + <<<'CODE_SAMPLE' +use PHPUnit\Framework\TestCase; + +final class SomeTest extends TestCase +{ + public function test() + { + $this->someMethod($this->createStub(SomeClass::class)); + } + + private function someMethod($someClass) + { + } +} +CODE_SAMPLE + ), + + ] + ); + } + + /** + * @return array> + */ + public function getNodeTypes(): array + { + return [StaticCall::class, MethodCall::class, New_::class]; + } + + /** + * @param MethodCall|StaticCall|New_ $node + */ + public function refactor(Node $node): MethodCall|StaticCall|New_|null + { + $scope = ScopeFetcher::fetch($node); + if (! $scope->isInClass()) { + return null; + } + + $classReflection = $scope->getClassReflection(); + if (! $classReflection->is(PHPUnitClassName::TEST_CASE)) { + return null; + } + + $hasChanges = false; + + foreach ($node->getArgs() as $arg) { + if (! $arg->value instanceof MethodCall) { + continue; + } + + $methodCall = $arg->value; + if (! $this->isName($methodCall->name, 'createMock')) { + continue; + } + + $methodCall->name = new Identifier('createStub'); + $hasChanges = true; + } + + if ($hasChanges) { + return $node; + } + + return null; + } +}