Skip to content

Commit

Permalink
Merge branch '11.1'
Browse files Browse the repository at this point in the history
  • Loading branch information
sebastianbergmann committed Apr 26, 2024
2 parents c9608ce + 296f314 commit 90010ca
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 17 deletions.
Expand Up @@ -14,14 +14,17 @@
/**
* @internal This class is not covered by the backward compatibility promise for PHPUnit
*/
final class ClassAlreadyExistsException extends \PHPUnit\Framework\Exception implements Exception
final class NameAlreadyInUseException extends \PHPUnit\Framework\Exception implements Exception
{
public function __construct(string $className)
/**
* @psalm-param class-string|trait-string $name
*/
public function __construct(string $name)
{
parent::__construct(
sprintf(
'Class "%s" already exists',
$className,
'The name "%s" is already in use',
$name,
),
);
}
Expand Down
24 changes: 13 additions & 11 deletions src/Framework/MockObject/Generator/Generator.php
Expand Up @@ -100,11 +100,11 @@ final class Generator
/**
* Returns a test double for the specified class.
*
* @throws ClassAlreadyExistsException
* @throws ClassIsEnumerationException
* @throws ClassIsFinalException
* @throws DuplicateMethodException
* @throws InvalidMethodNameException
* @throws NameAlreadyInUseException
* @throws OriginalConstructorInvocationRequiredException
* @throws ReflectionException
* @throws RuntimeException
Expand All @@ -121,7 +121,7 @@ public function testDouble(string $type, bool $mockObject, bool $markAsMockObjec
}

$this->ensureValidMethods($methods);
$this->ensureMockedClassDoesNotAlreadyExist($mockClassName);
$this->ensureNameForTestDoubleClassIsAvailable($mockClassName);

if (!$callOriginalConstructor && $callOriginalMethods) {
throw new OriginalConstructorInvocationRequiredException;
Expand Down Expand Up @@ -232,12 +232,12 @@ public function testDoubleForInterfaceIntersection(array $interfaces, bool $mock
*
* Concrete methods to mock can be specified with the $mockedMethods parameter.
*
* @throws ClassAlreadyExistsException
* @throws ClassIsEnumerationException
* @throws ClassIsFinalException
* @throws DuplicateMethodException
* @throws InvalidArgumentException
* @throws InvalidMethodNameException
* @throws NameAlreadyInUseException
* @throws OriginalConstructorInvocationRequiredException
* @throws ReflectionException
* @throws RuntimeException
Expand Down Expand Up @@ -292,12 +292,12 @@ interface_exists($originalClassName, $callAutoload)) {
*
* @psalm-param trait-string $traitName
*
* @throws ClassAlreadyExistsException
* @throws ClassIsEnumerationException
* @throws ClassIsFinalException
* @throws DuplicateMethodException
* @throws InvalidArgumentException
* @throws InvalidMethodNameException
* @throws NameAlreadyInUseException
* @throws OriginalConstructorInvocationRequiredException
* @throws ReflectionException
* @throws RuntimeException
Expand Down Expand Up @@ -987,17 +987,19 @@ private function ensureValidMethods(?array $methods): void
}

/**
* @throws ClassAlreadyExistsException
* @throws NameAlreadyInUseException
* @throws ReflectionException
*/
private function ensureMockedClassDoesNotAlreadyExist(string $mockClassName): void
private function ensureNameForTestDoubleClassIsAvailable(string $className): void
{
if ($mockClassName !== '' && class_exists($mockClassName, false)) {
$reflector = $this->reflectClass($mockClassName);
if ($className === '') {
return;
}

if (!$reflector->implementsInterface(MockObject::class)) {
throw new ClassAlreadyExistsException($mockClassName);
}
if (class_exists($className, false) ||
interface_exists($className, false) ||
trait_exists($className, false)) {
throw new NameAlreadyInUseException($className);
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/Framework/MockObject/MockBuilder.php
Expand Up @@ -16,12 +16,12 @@
use PHPUnit\Event\Facade as EventFacade;
use PHPUnit\Framework\Exception;
use PHPUnit\Framework\InvalidArgumentException;
use PHPUnit\Framework\MockObject\Generator\ClassAlreadyExistsException;
use PHPUnit\Framework\MockObject\Generator\ClassIsEnumerationException;
use PHPUnit\Framework\MockObject\Generator\ClassIsFinalException;
use PHPUnit\Framework\MockObject\Generator\DuplicateMethodException;
use PHPUnit\Framework\MockObject\Generator\Generator;
use PHPUnit\Framework\MockObject\Generator\InvalidMethodNameException;
use PHPUnit\Framework\MockObject\Generator\NameAlreadyInUseException;
use PHPUnit\Framework\MockObject\Generator\OriginalConstructorInvocationRequiredException;
use PHPUnit\Framework\MockObject\Generator\ReflectionException;
use PHPUnit\Framework\MockObject\Generator\RuntimeException;
Expand Down Expand Up @@ -77,12 +77,12 @@ public function __construct(TestCase $testCase, string $type)
/**
* Creates a mock object using a fluent interface.
*
* @throws ClassAlreadyExistsException
* @throws ClassIsEnumerationException
* @throws ClassIsFinalException
* @throws DuplicateMethodException
* @throws InvalidArgumentException
* @throws InvalidMethodNameException
* @throws NameAlreadyInUseException
* @throws OriginalConstructorInvocationRequiredException
* @throws ReflectionException
* @throws RuntimeException
Expand Down
12 changes: 12 additions & 0 deletions tests/unit/Framework/MockObject/Creation/MockBuilderTest.php
Expand Up @@ -16,13 +16,15 @@
use PHPUnit\Framework\Attributes\IgnorePhpunitDeprecations;
use PHPUnit\Framework\Attributes\Medium;
use PHPUnit\Framework\Attributes\TestDox;
use PHPUnit\Framework\MockObject\Generator\NameAlreadyInUseException;
use PHPUnit\Framework\TestCase;
use PHPUnit\TestFixture\MockObject\AbstractClass;
use PHPUnit\TestFixture\MockObject\ExtendableClass;
use PHPUnit\TestFixture\MockObject\InterfaceWithReturnTypeDeclaration;
use PHPUnit\TestFixture\MockObject\TraitWithConcreteAndAbstractMethod;

#[CoversClass(MockBuilder::class)]
#[CoversClass(NameAlreadyInUseException::class)]
#[CoversClass(CannotUseAddMethodsException::class)]
#[Group('test-doubles')]
#[Group('test-doubles/creation')]
Expand All @@ -42,6 +44,16 @@ public function testCanCreateMockObjectWithSpecifiedClassName(): void
$this->assertSame($className, $double::class);
}

#[TestDox('setMockClassName() cannot be used to configure the name of the mock object class when a class with that name already exists')]
public function testCannotCreateMockObjectWithSpecifiedClassNameWhenClassWithThatNameAlreadyExists(): void
{
$this->expectException(NameAlreadyInUseException::class);

$this->getMockBuilder(InterfaceWithReturnTypeDeclaration::class)
->setMockClassName(__CLASS__)
->getMock();
}

#[IgnorePhpunitDeprecations]
#[TestDox('addMethods() can be used to configure an additional method for the mock object class when the original class does not have a method of the same name')]
public function testCanCreateMockObjectForExtendableClassWhileAddingMethodsToIt(): void
Expand Down

0 comments on commit 90010ca

Please sign in to comment.