sebastianbergmann/phpunit · error · NameAlreadyInUseException

The name "%s" is already in use

Error message

The name "%s" is already in use

What it means

Thrown by Generator::ensureNameForTestDoubleClassIsAvailable() when a class, interface, or trait with the requested mock class name is already declared. The check uses class_exists/interface_exists/trait_exists with autoload disabled, so it only sees symbols already loaded in the current PHP process. Its purpose is to prevent a fatal 'cannot redeclare class' during eval() of the generated double.

Source

Thrown at src/Framework/MockObject/Generator/Generator.php:751

        if (preg_match('~\A[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*\z~', $className) === 0) {
            throw new InvalidClassNameException($className);
        }
    }

    /**
     * @throws NameAlreadyInUseException
     * @throws ReflectionException
     */
    private function ensureNameForTestDoubleClassIsAvailable(string $className): void
    {
        if ($className === '') {
            return;
        }

        if (class_exists($className, false) ||
            interface_exists($className, false) ||
            trait_exists($className, false)) {
            throw new NameAlreadyInUseException($className);
        }
    }

    /**
     * @template T of object
     *
     * @param class-string<T> $className
     *
     * @throws ReflectionException
     *
     * @return ReflectionClass<T>
     *
     * @phpstan-ignore throws.unusedType
     */
    private function reflectClass(string $className): ReflectionClass
    {
        try {
            $class = new ReflectionClass($className);

View on GitHub (pinned to f123cdb2a2)

Solutions

  1. Stop reusing fixed names: omit setMockClassName() so PHPUnit generates unique names per double.
  2. If a name is required, make it unique per call, e.g. setMockClassName('UserRepoMock_' . uniqid()).
  3. Rename the mock so it cannot collide with real classes; avoid names of classes loaded by your autoloader or bootstrap.

Example fix

// before
foreach ($ids as $id) {
    $mocks[] = $this->getMockBuilder(Repo::class)
        ->setMockClassName('RepoMock')
        ->getMock();
}

// after
foreach ($ids as $id) {
    $mocks[] = $this->getMockBuilder(Repo::class)
        ->setMockClassName('RepoMock_' . $id)
        ->getMock();
}
Defensive patterns

Strategy: validation

Validate before calling

$name = 'RepoMock_' . uniqid();
while (class_exists($name, false) || interface_exists($name, false) || trait_exists($name, false)) {
    $name .= '_';
}

Type guard

function classNameAvailable(string $name): bool
{
    return !class_exists($name, false)
        && !interface_exists($name, false)
        && !trait_exists($name, false);
}

Try / catch

try {
    $mock = $builder->setMockClassName($name)->getMock();
} catch (PHPUnit\Framework\MockObject\NameAlreadyInUseException $e) {
    // regenerate a unique name and rebuild the double
}

Prevention

When it happens

Trigger: setMockClassName('SomeExistingClass') where that class is already loaded; creating two doubles with the same explicit mock class name in one test run (e.g. from a loop or a shared helper); a generated name that collides with a class your bootstrap or another test loaded.

Common situations: Test helpers that hardcode a mock class name and are called more than once per process; data-provider loops creating mocks with a fixed name; parallel tests sharing a process with preloaded classes; long-running test suites where earlier generated classes remain declared.

Related errors


AI-assisted analysis of sebastianbergmann/phpunit@f123cdb2a2 (2026-08-23). Data as JSON: /api/errors/4bc25750f7608745. Report an issue: GitHub.