Skip to content

Commit 09133ce

Browse files
VincentLangletondrejmirtes
authored andcommitted
CreateStub returns a Stub
1 parent f26b2a2 commit 09133ce

File tree

7 files changed

+40
-5
lines changed

7 files changed

+40
-5
lines changed

extension.neon

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ parameters:
1212
- stubs/InvocationMocker.stub
1313
- stubs/MockBuilder.stub
1414
- stubs/MockObject.stub
15+
- stubs/Stub.stub
1516
- stubs/TestCase.stub
1617
exceptions:
1718
uncheckedExceptionRegexes:

src/PhpDoc/PHPUnit/MockObjectTypeNodeResolverExtension.php

+1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ public function resolve(TypeNode $typeNode, NameScope $nameScope): ?Type
3939
static $mockClassNames = [
4040
'PHPUnit_Framework_MockObject_MockObject' => true,
4141
'PHPUnit\Framework\MockObject\MockObject' => true,
42+
'PHPUnit\Framework\MockObject\Stub' => true,
4243
];
4344

4445
$types = $this->typeNodeResolver->resolveMultiple($typeNode->types, $nameScope);

src/Rules/PHPUnit/MockMethodCallRule.php

+6-2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use PHPStan\Type\ObjectType;
1313
use PHPUnit\Framework\MockObject\Builder\InvocationMocker;
1414
use PHPUnit\Framework\MockObject\MockObject;
15+
use PHPUnit\Framework\MockObject\Stub;
1516
use function array_filter;
1617
use function count;
1718
use function implode;
@@ -52,11 +53,14 @@ public function processNode(Node $node, Scope $scope): array
5253

5354
if (
5455
$type instanceof IntersectionType
55-
&& in_array(MockObject::class, $type->getReferencedClasses(), true)
56+
&& (
57+
in_array(MockObject::class, $type->getReferencedClasses(), true)
58+
|| in_array(Stub::class, $type->getReferencedClasses(), true)
59+
)
5660
&& !$type->hasMethod($method)->yes()
5761
) {
5862
$mockClass = array_filter($type->getReferencedClasses(), static function (string $class): bool {
59-
return $class !== MockObject::class;
63+
return $class !== MockObject::class && $class !== Stub::class;
6064
});
6165

6266
return [

stubs/Stub.stub

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php
2+
3+
namespace PHPUnit\Framework\MockObject;
4+
5+
interface Stub
6+
{
7+
8+
}

stubs/TestCase.stub

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,15 @@ namespace PHPUnit\Framework;
44

55
use PHPUnit\Framework\MockObject\MockObject;
66
use PHPUnit\Framework\MockObject\MockBuilder;
7+
use PHPUnit\Framework\MockObject\Stub;
78

89
class TestCase
910
{
1011

1112
/**
1213
* @template T
1314
* @phpstan-param class-string<T> $originalClassName
14-
* @phpstan-return MockObject&T
15+
* @phpstan-return Stub&T
1516
*/
1617
public function createStub($originalClassName) {}
1718

tests/Rules/PHPUnit/MockMethodCallRuleTest.php

+12-2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use PHPStan\Rules\Rule;
66
use PHPStan\Testing\RuleTestCase;
7+
use function interface_exists;
78

89
/**
910
* @extends RuleTestCase<MockMethodCallRule>
@@ -18,7 +19,7 @@ protected function getRule(): Rule
1819

1920
public function testRule(): void
2021
{
21-
$this->analyse([__DIR__ . '/data/mock-method-call.php'], [
22+
$expectedErrors = [
2223
[
2324
'Trying to mock an undefined method doBadThing() on class MockMethodCall\Bar.',
2425
15,
@@ -27,7 +28,16 @@ public function testRule(): void
2728
'Trying to mock an undefined method doBadThing() on class MockMethodCall\Bar.',
2829
20,
2930
],
30-
]);
31+
];
32+
33+
if (interface_exists('PHPUnit\Framework\MockObject\Builder\InvocationStubber')) {
34+
$expectedErrors[] = [
35+
'Trying to mock an undefined method doBadThing() on class MockMethodCall\Bar.',
36+
36,
37+
];
38+
}
39+
40+
$this->analyse([__DIR__ . '/data/mock-method-call.php'], $expectedErrors);
3141
}
3242

3343
/**

tests/Rules/PHPUnit/data/mock-method-call.php

+10
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,16 @@ public function testWithAnotherObject()
2626
$bar->method('doBadThing');
2727
}
2828

29+
public function testGoodMethodOnStub()
30+
{
31+
$this->createStub(Bar::class)->method('doThing');
32+
}
33+
34+
public function testBadMethodOnStub()
35+
{
36+
$this->createStub(Bar::class)->method('doBadThing');
37+
}
38+
2939
}
3040

3141
class Bar {

0 commit comments

Comments
 (0)