Skip to content

Commit 63183f2

Browse files
The configured name for a test double class may also not be avaiable because an interface or a trait of the same name already exists
1 parent b7e95f5 commit 63183f2

File tree

4 files changed

+25
-20
lines changed

4 files changed

+25
-20
lines changed

src/Framework/MockObject/Generator/Exception/ClassAlreadyExistsException.php renamed to src/Framework/MockObject/Generator/Exception/NameAlreadyInUseException.php

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,17 @@
1414
/**
1515
* @internal This class is not covered by the backward compatibility promise for PHPUnit
1616
*/
17-
final class ClassAlreadyExistsException extends \PHPUnit\Framework\Exception implements Exception
17+
final class NameAlreadyInUseException extends \PHPUnit\Framework\Exception implements Exception
1818
{
19-
public function __construct(string $className)
19+
/**
20+
* @psalm-param class-string|trait-string $name
21+
*/
22+
public function __construct(string $name)
2023
{
2124
parent::__construct(
2225
sprintf(
23-
'Class "%s" already exists',
24-
$className,
26+
'The name "%s" is already in use',
27+
$name,
2528
),
2629
);
2730
}

src/Framework/MockObject/Generator/Generator.php

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -92,12 +92,12 @@ final class Generator
9292
/**
9393
* Returns a test double for the specified class.
9494
*
95-
* @throws ClassAlreadyExistsException
9695
* @throws ClassIsEnumerationException
9796
* @throws ClassIsFinalException
9897
* @throws ClassIsReadonlyException
9998
* @throws DuplicateMethodException
10099
* @throws InvalidMethodNameException
100+
* @throws NameAlreadyInUseException
101101
* @throws OriginalConstructorInvocationRequiredException
102102
* @throws ReflectionException
103103
* @throws RuntimeException
@@ -114,7 +114,7 @@ public function testDouble(string $type, bool $mockObject, ?array $methods = [],
114114
}
115115

116116
$this->ensureValidMethods($methods);
117-
$this->ensureMockedClassDoesNotAlreadyExist($mockClassName);
117+
$this->ensureNameForTestDoubleClassIsAvailable($mockClassName);
118118

119119
if (!$callOriginalConstructor && $callOriginalMethods) {
120120
throw new OriginalConstructorInvocationRequiredException;
@@ -219,13 +219,13 @@ public function testDoubleForInterfaceIntersection(array $interfaces, bool $mock
219219
*
220220
* Concrete methods to mock can be specified with the $mockedMethods parameter.
221221
*
222-
* @throws ClassAlreadyExistsException
223222
* @throws ClassIsEnumerationException
224223
* @throws ClassIsFinalException
225224
* @throws ClassIsReadonlyException
226225
* @throws DuplicateMethodException
227226
* @throws InvalidArgumentException
228227
* @throws InvalidMethodNameException
228+
* @throws NameAlreadyInUseException
229229
* @throws OriginalConstructorInvocationRequiredException
230230
* @throws ReflectionException
231231
* @throws RuntimeException
@@ -279,13 +279,13 @@ interface_exists($originalClassName, $callAutoload)) {
279279
*
280280
* @psalm-param trait-string $traitName
281281
*
282-
* @throws ClassAlreadyExistsException
283282
* @throws ClassIsEnumerationException
284283
* @throws ClassIsFinalException
285284
* @throws ClassIsReadonlyException
286285
* @throws DuplicateMethodException
287286
* @throws InvalidArgumentException
288287
* @throws InvalidMethodNameException
288+
* @throws NameAlreadyInUseException
289289
* @throws OriginalConstructorInvocationRequiredException
290290
* @throws ReflectionException
291291
* @throws RuntimeException
@@ -922,17 +922,19 @@ private function ensureValidMethods(?array $methods): void
922922
}
923923

924924
/**
925-
* @throws ClassAlreadyExistsException
925+
* @throws NameAlreadyInUseException
926926
* @throws ReflectionException
927927
*/
928-
private function ensureMockedClassDoesNotAlreadyExist(string $mockClassName): void
928+
private function ensureNameForTestDoubleClassIsAvailable(string $className): void
929929
{
930-
if ($mockClassName !== '' && class_exists($mockClassName, false)) {
931-
$reflector = $this->reflectClass($mockClassName);
930+
if ($className === '') {
931+
return;
932+
}
932933

933-
if (!$reflector->implementsInterface(MockObject::class)) {
934-
throw new ClassAlreadyExistsException($mockClassName);
935-
}
934+
if (class_exists($className, false) ||
935+
interface_exists($className, false) ||
936+
trait_exists($className, false)) {
937+
throw new NameAlreadyInUseException($className);
936938
}
937939
}
938940

src/Framework/MockObject/MockBuilder.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@
1414
use function trait_exists;
1515
use PHPUnit\Framework\Exception;
1616
use PHPUnit\Framework\InvalidArgumentException;
17-
use PHPUnit\Framework\MockObject\Generator\ClassAlreadyExistsException;
1817
use PHPUnit\Framework\MockObject\Generator\ClassIsEnumerationException;
1918
use PHPUnit\Framework\MockObject\Generator\ClassIsFinalException;
2019
use PHPUnit\Framework\MockObject\Generator\ClassIsReadonlyException;
2120
use PHPUnit\Framework\MockObject\Generator\DuplicateMethodException;
2221
use PHPUnit\Framework\MockObject\Generator\Generator;
2322
use PHPUnit\Framework\MockObject\Generator\InvalidMethodNameException;
23+
use PHPUnit\Framework\MockObject\Generator\NameAlreadyInUseException;
2424
use PHPUnit\Framework\MockObject\Generator\OriginalConstructorInvocationRequiredException;
2525
use PHPUnit\Framework\MockObject\Generator\ReflectionException;
2626
use PHPUnit\Framework\MockObject\Generator\RuntimeException;
@@ -76,13 +76,13 @@ public function __construct(TestCase $testCase, string $type)
7676
/**
7777
* Creates a mock object using a fluent interface.
7878
*
79-
* @throws ClassAlreadyExistsException
8079
* @throws ClassIsEnumerationException
8180
* @throws ClassIsFinalException
8281
* @throws ClassIsReadonlyException
8382
* @throws DuplicateMethodException
8483
* @throws InvalidArgumentException
8584
* @throws InvalidMethodNameException
85+
* @throws NameAlreadyInUseException
8686
* @throws OriginalConstructorInvocationRequiredException
8787
* @throws ReflectionException
8888
* @throws RuntimeException

tests/unit/Framework/MockObject/Creation/MockBuilderTest.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,15 @@
1515
use PHPUnit\Framework\Attributes\Group;
1616
use PHPUnit\Framework\Attributes\Medium;
1717
use PHPUnit\Framework\Attributes\TestDox;
18-
use PHPUnit\Framework\MockObject\Generator\ClassAlreadyExistsException;
18+
use PHPUnit\Framework\MockObject\Generator\NameAlreadyInUseException;
1919
use PHPUnit\Framework\TestCase;
2020
use PHPUnit\TestFixture\MockObject\AbstractClass;
2121
use PHPUnit\TestFixture\MockObject\ExtendableClass;
2222
use PHPUnit\TestFixture\MockObject\InterfaceWithReturnTypeDeclaration;
2323
use PHPUnit\TestFixture\MockObject\TraitWithConcreteAndAbstractMethod;
2424

2525
#[CoversClass(MockBuilder::class)]
26-
#[CoversClass(ClassAlreadyExistsException::class)]
26+
#[CoversClass(NameAlreadyInUseException::class)]
2727
#[CoversClass(CannotUseAddMethodsException::class)]
2828
#[Group('test-doubles')]
2929
#[Group('test-doubles/creation')]
@@ -46,7 +46,7 @@ public function testCanCreateMockObjectWithSpecifiedClassName(): void
4646
#[TestDox('setMockClassName() cannot be used to configure the name of the mock object class when a class with that name already exists')]
4747
public function testCannotCreateMockObjectWithSpecifiedClassNameWhenClassWithThatNameAlreadyExists(): void
4848
{
49-
$this->expectException(ClassAlreadyExistsException::class);
49+
$this->expectException(NameAlreadyInUseException::class);
5050

5151
$this->getMockBuilder(InterfaceWithReturnTypeDeclaration::class)
5252
->setMockClassName(__CLASS__)

0 commit comments

Comments
 (0)