sebastianbergmann/phpunit · error · MethodCannotBeConfiguredException

Trying to configure method "%s" which cannot be configured b

Error message

Trying to configure method "%s" which cannot be configured because it does not exist, has not been specified, is final, or is static

What it means

Thrown by Invocation implementation when you call ->method($name) on a mock/stub builder and $name (compared lower-case against the double's configurableMethods list) is not configurable. A method is configurable only if it exists on the double and is neither final nor static; for partial mocks (onlyMethods()) it must also have been included in the method list.

Source

Thrown at src/Framework/MockObject/Runtime/AbstractInvocationImplementation.php:92

    {
        if ($this->matcher->hasMethodNameRule()) {
            throw new MethodNameAlreadyConfiguredException;
        }

        if ($constraint instanceof PropertyHook) {
            $constraint = $constraint->asString();
        }

        if (is_string($constraint)) {
            $this->configurableMethodNames ??= array_flip(
                array_map(
                    static fn (ConfigurableMethod $configurable) => strtolower($configurable->name()),
                    $this->configurableMethods,
                ),
            );

            if (!array_key_exists(strtolower($constraint), $this->configurableMethodNames)) {
                throw new MethodCannotBeConfiguredException($constraint);
            }
        }

        $this->matcher->setMethodNameRule(new Rule\MethodName($constraint));

        return $this;
    }

    /**
     * @return $this
     */
    final public function will(Stub $stub): InvocationStubber
    {
        $this->matcher->setStub($stub);

        return $this;
    }

View on GitHub (pinned to f123cdb2a2)

Solutions

  1. Check the method exists on the doubled type and is not final/static: (new ReflectionMethod(C::class, 'name'))->isFinal().
  2. For partial mocks, add the method to onlyMethods([...]) (or switch to excludeMethods()/addMethods() as appropriate).
  3. If the method is final, remove the ->method() expectation and let the real implementation run, or ask the upstream library to un-finalize it (or use a wrapper interface you control).
  4. Fix the typo; the comparison is case-insensitive, so capitalization is not the problem.

Example fix

// before
$mock = $this->getMockBuilder(Service::class)
    ->onlyMethods(['authorize'])
    ->getMock();
$mock->expects($this->once())->method('charge'); // charge() not in list

// after
$mock = $this->getMockBuilder(Service::class)
    ->onlyMethods(['authorize', 'charge'])
    ->getMock();
$mock->expects($this->once())->method('charge');
Defensive patterns

Strategy: validation

Validate before calling

$reflection = new ReflectionClass(Service::class);
$configurable = [];
foreach ($reflection->getMethods() as $m) {
    if (!$m->isFinal() && !$m->isStatic() && in_array($m->getName(), $wanted, true)) {
        $configurable[] = $m->getName();
    }
}

Type guard

function isConfigurable(string $class, string $method, array $partialList = null): bool
{
    $r = new ReflectionClass($class);
    if (!$r->hasMethod($method)) {
        return false;
    }
    $m = $r->getMethod($method);

    return !$m->isFinal()
        && !$m->isStatic()
        && ($partialList === null || in_array($method, $partialList, true));
}

Try / catch

try {
    $mock->expects($this->once())->method($name);
} catch (PHPUnit\Framework\MockObject\MethodCannotBeConfiguredException $e) {
    // check reflection for final/static and adjust the onlyMethods() list
}

Prevention

When it happens

Trigger: Typo in ->method('savve') (matching is case-insensitive, so only wrong characters matter); configuring a method you excluded via onlyMethods(['otherMethod']); ->method() on a final method or a static method; configuring an interface method on a stub of a different interface; ->method('__construct').

Common situations: Partial mocks where production code calls a method the test author forgot to list in onlyMethods(); mocking classes with final methods (common after a dependency made methods final); upgrading a dependency whose method became final or static; using createStub() for an intersection of interfaces and configuring a method from a third interface.

Related errors


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