Skip to content

Commit b7c3087

Browse files
committed
add fixtures to handle
1 parent 167ec7b commit b7c3087

File tree

4 files changed

+95
-26
lines changed

4 files changed

+95
-26
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
namespace Rector\PHPUnit\Tests\PHPUnit120\Rector\Class_\AllowMockObjectsWithoutExpectationsAttributeRector\Fixture;
4+
5+
use PHPUnit\Framework\TestCase;
6+
7+
final class SkipIfAllTestsMethodsDefineExpectations 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+
}
15+
16+
public function testOne()
17+
{
18+
$this->someMock->method('doSomething')->willReturn('value');
19+
}
20+
21+
public function testTwo()
22+
{
23+
$this->someMock->method('doSomethingElse')->willReturn('another value');
24+
}
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
namespace Rector\PHPUnit\Tests\PHPUnit120\Rector\Class_\AllowMockObjectsWithoutExpectationsAttributeRector\Fixture;
4+
5+
use PHPUnit\Framework\TestCase;
6+
7+
final class SkipIfMockNotUsedIn2TestMethods 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+
}
15+
16+
public function testOne()
17+
{
18+
}
19+
20+
public function testTwo()
21+
{
22+
23+
}
24+
}

rules-tests/PHPUnit120/Rector/Class_/AllowMockObjectsWithoutExpectationsAttributeRector/Fixture/some_class.php.inc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,11 @@ final class SomeClass extends TestCase
1515

1616
public function testOne()
1717
{
18+
$this->someMock->method('doSomething')->willReturn('value');
1819
}
1920

2021
public function testTwo()
2122
{
22-
2323
}
2424
}
2525

@@ -43,11 +43,11 @@ final class SomeClass extends TestCase
4343

4444
public function testOne()
4545
{
46+
$this->someMock->method('doSomething')->willReturn('value');
4647
}
4748

4849
public function testTwo()
4950
{
50-
5151
}
5252
}
5353

rules/PHPUnit120/Rector/Class_/AllowMockObjectsWithoutExpectationsAttributeRector.php

Lines changed: 44 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use Rector\PHPUnit\Enum\PHPUnitClassName;
1818
use Rector\PHPUnit\NodeAnalyzer\TestsNodeAnalyzer;
1919
use Rector\Rector\AbstractRector;
20+
use Rector\ValueObject\MethodName;
2021
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
2122
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
2223

@@ -44,30 +45,14 @@ public function getNodeTypes(): array
4445
*/
4546
public function refactor(Node $node): ?Class_
4647
{
47-
if (! $this->testsNodeAnalyzer->isInTestClass($node)) {
48+
if ($this->shouldSkipClass($node)) {
4849
return null;
4950
}
5051

51-
// attribute must exist for the rule to work
52-
if (! $this->reflectionProvider->hasClass(PHPUnitAttribute::ALLOW_MOCK_OBJECTS_WITHOUT_EXPECTATIONS)) {
53-
return null;
54-
}
55-
56-
// already filled
57-
if ($this->attributeFinder->hasAttributeByClasses(
58-
$node,
59-
[PHPUnitAttribute::ALLOW_MOCK_OBJECTS_WITHOUT_EXPECTATIONS]
60-
)) {
61-
return null;
62-
}
63-
64-
// has mock objects properties and setUp() method?
65-
66-
if (! $node->getMethod('setUp') instanceof ClassMethod) {
67-
return null;
68-
}
52+
$mockObjectPropertyNames = $this->matchMockObjectPropertyNames($node);
6953

70-
if (! $this->hasMockObjectProperty($node)) {
54+
// there are no mock object properties
55+
if ($mockObjectPropertyNames === []) {
7156
return null;
7257
}
7358

@@ -76,6 +61,9 @@ public function refactor(Node $node): ?Class_
7661

7762
foreach ($node->getMethods() as $classMethod) {
7863
if ($this->testsNodeAnalyzer->isTestClassMethod($classMethod)) {
64+
// is a mock property used in the method?
65+
// skip if so
66+
7967
++$testMethodCount;
8068
}
8169
}
@@ -153,18 +141,50 @@ public function testTwo(): void
153141

154142
}
155143

156-
private function hasMockObjectProperty(Class_ $class): bool
144+
/**
145+
* @return string[]
146+
*/
147+
private function matchMockObjectPropertyNames(Class_ $class): array
157148
{
149+
$propertyNames = [];
150+
158151
foreach ($class->getProperties() as $property) {
159152
if (! $property->type instanceof Name) {
160153
continue;
161154
}
162155

163-
if ($this->isName($property->type, PHPUnitClassName::MOCK_OBJECT)) {
164-
return true;
156+
if (! $this->isName($property->type, PHPUnitClassName::MOCK_OBJECT)) {
157+
continue;
165158
}
159+
160+
$propertyNames[] = $this->getName($property->props[0]);
161+
}
162+
163+
return $propertyNames;
164+
}
165+
166+
private function shouldSkipClass(Class_ $class): bool
167+
{
168+
if (! $this->testsNodeAnalyzer->isInTestClass($class)) {
169+
return true;
166170
}
167171

168-
return false;
172+
// attribute must exist for the rule to work
173+
if (! $this->reflectionProvider->hasClass(PHPUnitAttribute::ALLOW_MOCK_OBJECTS_WITHOUT_EXPECTATIONS)) {
174+
return true;
175+
}
176+
177+
// already filled
178+
if ($this->attributeFinder->hasAttributeByClasses(
179+
$class,
180+
[PHPUnitAttribute::ALLOW_MOCK_OBJECTS_WITHOUT_EXPECTATIONS]
181+
)) {
182+
return true;
183+
}
184+
185+
// has mock objects properties and setUp() method?
186+
187+
$setupClassMethod = $class->getMethod(MethodName::SET_UP);
188+
return ! $setupClassMethod instanceof ClassMethod;
169189
}
170190
}

0 commit comments

Comments
 (0)