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
- Check the method exists on the doubled type and is not final/static: (new ReflectionMethod(C::class, 'name'))->isFinal().
- For partial mocks, add the method to onlyMethods([...]) (or switch to excludeMethods()/addMethods() as appropriate).
- 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).
- 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
- Keep the onlyMethods() list in the same test method as the expectations that use it so they stay in sync.
- Before mocking a class for the first time, scan it for final/static methods and design the partial mock around them.
- When upgrading dependencies, grep their changelogs for 'final' keyword additions to methods you stub.
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
- Cannot double method with invalid name "%s"
- Cannot double using a method list that contains duplicates:
- Cannot use "%s" as the name of a test double class because i
- The name "%s" is already in use
- Method %s may not return value of type %s, its declared retu
AI-assisted analysis of sebastianbergmann/phpunit@f123cdb2a2 (2026-08-23).
Data as JSON: /api/errors/dd47cca2be8f88b7.
Report an issue: GitHub.