Skip to content

Commit afe1113

Browse files
committed
add fixture
1 parent d99e5c8 commit afe1113

File tree

2 files changed

+92
-0
lines changed

2 files changed

+92
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<?php
2+
3+
namespace Rector\PHPUnit\Tests\PHPUnit120\Rector\Class_\AllowMockObjectsWithoutExpectationsAttributeRector\Fixture;
4+
5+
use PHPUnit\Framework\TestCase;
6+
7+
final class AddToSetupWhenNoExpects extends TestCase
8+
{
9+
private \PHPUnit\Framework\MockObject\MockObject $someMock;
10+
11+
protected function setUp(): void
12+
{
13+
$this->someMock = $this->createMock(\stdClass::class);
14+
$this->someMock->method('some')->willReturn(true);
15+
}
16+
17+
public function testOne()
18+
{
19+
}
20+
21+
public function testTwo()
22+
{
23+
}
24+
}
25+
26+
?>
27+
-----
28+
<?php
29+
30+
namespace Rector\PHPUnit\Tests\PHPUnit120\Rector\Class_\AllowMockObjectsWithoutExpectationsAttributeRector\Fixture;
31+
32+
use PHPUnit\Framework\TestCase;
33+
34+
#[\PHPUnit\Framework\Attributes\AllowMockObjectsWithoutExpectations]
35+
final class AddToSetupWhenNoExpects extends TestCase
36+
{
37+
private \PHPUnit\Framework\MockObject\MockObject $someMock;
38+
39+
protected function setUp(): void
40+
{
41+
$this->someMock = $this->createMock(\stdClass::class);
42+
$this->someMock->method('some')->willReturn(true);
43+
}
44+
45+
public function testOne()
46+
{
47+
}
48+
49+
public function testTwo()
50+
{
51+
}
52+
}
53+
54+
?>

rules/PHPUnit120/Rector/Class_/AllowMockObjectsWithoutExpectationsAttributeRector.php

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use PhpParser\Node\Stmt\Class_;
1515
use PhpParser\Node\Stmt\ClassMethod;
1616
use PHPStan\Reflection\ReflectionProvider;
17+
use PHPStan\Type\ObjectType;
1718
use Rector\Doctrine\NodeAnalyzer\AttributeFinder;
1819
use Rector\PhpParser\Node\BetterNodeFinder;
1920
use Rector\PHPUnit\Enum\PHPUnitAttribute;
@@ -86,6 +87,16 @@ public function refactor(Node $node): ?Class_
8687
}
8788
}
8889

90+
// or find a ->method() calls on a setUp() mocked property
91+
$hasAnyMethodInSetup = $this->isMissingExpectsOnMockObjectMethodCallInSetUp($node);
92+
if ($hasAnyMethodInSetup && $testMethodCount > 1) {
93+
$node->attrGroups[] = new AttributeGroup([
94+
new Attribute(new FullyQualified(PHPUnitAttribute::ALLOW_MOCK_OBJECTS_WITHOUT_EXPECTATIONS)),
95+
]);
96+
97+
return $node;
98+
}
99+
89100
if (! $this->shouldAddAttribute($missedTestMethodsByMockPropertyName)) {
90101
return null;
91102
}
@@ -269,4 +280,31 @@ private function isAtLeastOneMockPropertyMockedOnce(array $usingTestMethodsByMoc
269280

270281
return false;
271282
}
283+
284+
private function isMissingExpectsOnMockObjectMethodCallInSetUp(Class_ $class): bool
285+
{
286+
$setupClassMethod = $class->getMethod(MethodName::SET_UP);
287+
if (! $setupClassMethod instanceof ClassMethod) {
288+
return false;
289+
}
290+
291+
/** @var MethodCall[] $methodCalls */
292+
$methodCalls = $this->betterNodeFinder->findInstancesOfScoped(
293+
(array) $setupClassMethod->stmts,
294+
MethodCall::class
295+
);
296+
foreach ($methodCalls as $methodCall) {
297+
if (! $this->isName($methodCall->name, 'method')) {
298+
continue;
299+
}
300+
301+
if (! $this->isObjectType($methodCall->var, new ObjectType(PHPUnitClassName::MOCK_OBJECT))) {
302+
continue;
303+
}
304+
305+
return true;
306+
}
307+
308+
return false;
309+
}
272310
}

0 commit comments

Comments
 (0)