Skip to content

Commit 9c7d4da

Browse files
committed
[CodeQuality] Skip dynamic method call in AllowMockObjectsForDataProviderRector
Fixes rectorphp/rector#9877 A dynamic call like `$sut->$method()` was treated as a literal `->method()` call because the variable name resolved to "method". Skip when the call name is not an Identifier. Claude-Session: https://claude.ai/code/session_01JHq62QomBxARKhP7RxQ6gJ
1 parent 126d4a6 commit 9c7d4da

2 files changed

Lines changed: 31 additions & 0 deletions

File tree

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Rector\PHPUnit\Tests\PHPUnit120\Rector\Class_\AllowMockObjectsForDataProviderRector\Fixture;
6+
7+
use PHPUnit\Framework\Attributes\DataProvider;
8+
use PHPUnit\Framework\TestCase;
9+
10+
final class SkipDynamicMethodCall extends TestCase
11+
{
12+
#[DataProvider('methodNameProvider')]
13+
public function testUnusableMethods(string $method): void
14+
{
15+
$sut = new \stdClass();
16+
17+
$this->expectException(\RuntimeException::class);
18+
19+
$sut->$method();
20+
}
21+
22+
public static function methodNameProvider(): iterable
23+
{
24+
yield ['realMethodName'];
25+
}
26+
}

‎rules/CodeQuality/NodeAnalyser/MockObjectExprDetector.php‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@ public function hasMethodCallWithoutExpects(ClassMethod $classMethod): bool
3636
$methodCalls = $this->betterNodeFinder->findInstancesOfScoped((array) $classMethod->stmts, [MethodCall::class]);
3737

3838
foreach ($methodCalls as $methodCall) {
39+
// dynamic method call, e.g. $sut->$method(), is not a literal ->method() call
40+
if (! $methodCall->name instanceof Identifier) {
41+
continue;
42+
}
43+
3944
if (! $this->nodeNameResolver->isName($methodCall->name, 'method')) {
4045
continue;
4146
}

0 commit comments

Comments
 (0)