mockery/mockery · error · Mockery\Exception\RuntimeException
Could not load mock %s, class already exists
Error message
Could not load mock %s, class already exists
What it means
After the generator produces a mock class definition, Container::generateMock() checks whether that class name already exists (without triggering autoload). If it exists and does not implement LegacyMockInterface - meaning it is a real pre-existing class, not a Mockery-generated mock - Mockery refuses to redefine it and throws RuntimeException.
Source
Thrown at library/Mockery/Container.php:572
}
/**
* @return class-string
*
* @throws Throwable
*/
private function generateMock(MockConfiguration $mockConfiguration): string
{
$mockDefinition = $this->getGenerator()
->generate($mockConfiguration);
$className = $mockDefinition->getClassName();
if (class_exists($className, $attemptAutoload = false)) {
$reflectionClass = new ReflectionClass($className);
if (! $reflectionClass->implementsInterface(LegacyMockInterface::class)) {
throw new RuntimeException(sprintf('Could not load mock %s, class already exists', $className));
}
}
$this->getLoader()
->load($mockDefinition);
return $className;
}
/**
* @return null|Closure(MockInterface):void
*/
private function handleClosure(array &$arguments): ?Closure
{
if (count($arguments) < 2) {
return null;
}
View on GitHub (pinned to c6401d35bc)
Solutions
- Create the overload mock before anything autoloads the real class, and isolate such tests with @runInSeparateProcess + @preserveGlobalState disabled
- Prefer passing an instance (Mockery::mock(new Service())) over 'overload:' where possible
- Choose named-mock names that never collide with real class names
Example fix
// before
use App\Mailer; // real class now loaded
$mailer = Mockery::mock('overload:App\Mailer'); // throws: class already exists
// after
/**
* @runInSeparateProcess
* @preserveGlobalState disabled
*/
public function testMailSending(): void {
$mailer = Mockery::mock('overload:App\Mailer'); // created before autoloader loads the class
// ...
} Defensive patterns
Strategy: validation
Validate before calling
// Before an overload mock, ensure the real class is not loaded yet:
if (class_exists($targetClass, false)) {
throw new RuntimeException($targetClass . ' already loaded; overload mock impossible in this process');
}
$mock = Mockery::mock('overload:' . $targetClass); Prevention
- Isolate overload tests with @runInSeparateProcess and @preserveGlobalState disabled
- Create the overload mock before anything can autoload the real class (no use statements pulling it in earlier)
- Avoid mock names equal to real class names; prefer instance mocks (passing an object) over 'overload:'
When it happens
Trigger: Mockery::mock('overload:App\Service') when App\Service has already been autoloaded earlier in the process; Mockery::namedMock('SomeRealClass') where a class with that name exists; creating the same overloaded mock twice in one process (e.g. between tests without process isolation).
Common situations: Overload (instance-mock) tests in long-running suites (Paratest, Laravel) where the real class got loaded by another test first; mocks created in PHPUnit data providers; mock names chosen to equal real class names.
Related errors
- No expectations have been added to this composite expectatio
- Matcher class must implement %s, '%s' given.
- Internal class parameter overriding is not available in PHP
- You have not declared any mocks yet
- The mock named '%s' has been already defined with a differen
AI-assisted analysis of mockery/mockery@c6401d35bc (2026-08-21).
Data as JSON: /api/errors/edd3ba4296dd8af3.
Report an issue: GitHub.