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

  1. Create the overload mock before anything autoloads the real class, and isolate such tests with @runInSeparateProcess + @preserveGlobalState disabled
  2. Prefer passing an instance (Mockery::mock(new Service())) over 'overload:' where possible
  3. 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

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


AI-assisted analysis of mockery/mockery@c6401d35bc (2026-08-21). Data as JSON: /api/errors/edd3ba4296dd8af3. Report an issue: GitHub.