From 935c6864d2bf2266e0934c32f6c2aa70e302343c Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Mon, 29 Jun 2026 22:13:51 +0200 Subject: [PATCH] [PHPUnit120] Skip PropertyCreateMockToCreateStubRector for property with expects() nested in closure --- .../skip_property_used_in_closure.php.inc | 23 +++++++++++++++++++ .../NodeAnalyser/MockObjectExprDetector.php | 5 ++-- 2 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 rules-tests/PHPUnit120/Rector/Class_/PropertyCreateMockToCreateStubRector/Fixture/skip_property_used_in_closure.php.inc diff --git a/rules-tests/PHPUnit120/Rector/Class_/PropertyCreateMockToCreateStubRector/Fixture/skip_property_used_in_closure.php.inc b/rules-tests/PHPUnit120/Rector/Class_/PropertyCreateMockToCreateStubRector/Fixture/skip_property_used_in_closure.php.inc new file mode 100644 index 000000000..749efdbcb --- /dev/null +++ b/rules-tests/PHPUnit120/Rector/Class_/PropertyCreateMockToCreateStubRector/Fixture/skip_property_used_in_closure.php.inc @@ -0,0 +1,23 @@ +someMock = $this->createMock(\stdClass::class); + } + + public function testThis() + { + $builder = $this->createMock(\stdClass::class); + $builder->method('addEventListener')->willReturnCallback(function () { + $this->someMock->expects($this->once())->method('something'); + }); + } +} diff --git a/rules/CodeQuality/NodeAnalyser/MockObjectExprDetector.php b/rules/CodeQuality/NodeAnalyser/MockObjectExprDetector.php index 2ffc902ab..2a11faf83 100644 --- a/rules/CodeQuality/NodeAnalyser/MockObjectExprDetector.php +++ b/rules/CodeQuality/NodeAnalyser/MockObjectExprDetector.php @@ -141,9 +141,10 @@ public function isPropertyUsedForMocking(Class_ $class, string $propertyName): b return true; } - // find out, how many are used in call likes as args + // find out, how many are used in call likes as args; + // not scoped on purpose, as expects() can be nested in closures, e.g. willReturnCallback() /** @var array $methodCalls */ - $methodCalls = $this->betterNodeFinder->findInstancesOfScoped($class->getMethods(), [MethodCall::class]); + $methodCalls = $this->betterNodeFinder->findInstancesOf($class->getMethods(), [MethodCall::class]); foreach ($methodCalls as $methodCall) { if (! $methodCall->var instanceof PropertyFetch) {