sebastianbergmann/phpunit · error · ComparisonMethodDoesNotDeclareBoolReturnTypeException
Comparison method :: () does not declare bool return type.
Error message
Comparison method %s::%s() does not declare bool return type.
What it means
For assertObjectEquals(), PHPUnit requires the comparison method on the actual object to declare an explicit bool return type, because the constraint's return value drives pass/fail. This variant is thrown when ReflectionMethod::hasReturnType() is false, i.e. the method exists but has no return type at all.
Solutions
- Add the bool return type to the comparison method: `public function equals(self $other): bool`
- If you cannot change the class, use assertEquals() instead of assertObjectEquals()
Example fix
// before
class Email
{
public function equals(self $other) // no return type
{
return $this->value === $other->value;
}
}
// after
class Email
{
public function equals(self $other): bool
{
return $this->value === $other->value;
}
} Defensive patterns
Strategy: type-guard
Type guard
function comparisonMethodHasReturnType(object $actual, string $method = 'equals'): bool
{
$m = (new ReflectionObject($actual))->getMethod($method);
return $m->hasReturnType()
&& $m->getReturnType() instanceof \ReflectionNamedType
&& $m->getReturnType()->getName() === 'bool'
&& !$m->getReturnType()->allowsNull();
}
if (!comparisonMethodHasReturnType($actual)) {
$this->markTestIncomplete('equals() must declare `: bool`');
} Prevention
- Use the exact template `public function equals(self $other): bool` for every comparator intended for assertObjectEquals()
- Enforce native return types project-wide (PHP 7.4+ / PS-12 style) so untyped methods cannot survive
When it happens
Trigger: assertObjectEquals($expected, $actual) where the actual class's equals() (or custom-named method) is declared without a return type, e.g. `public function equals($other)` or `public function equals(self $other) { ... }` with no `: bool`.
Common situations: Legacy pre-PHP-7.4 codebases where return types were not used; equals() methods ported from Java that return bool but never declared the type; generated code or DTO builders that omit return types; teams adding assertObjectEquals() to an existing untyped codebase.
Related errors
- Comparison method :: () does not declare exactly one…
- Comparison method :: () does not exist.
- Parameter of comparison method
- is not an accepted argument type for comparison method :…
- At least two interfaces must be specified
AI-assisted analysis of sebastianbergmann/phpunit@f123cdb2a2 (2026-08-23).
Data as JSON: /api/errors/fd4b6277fb4803b8.
Report an issue: GitHub.
Appendix: source
Thrown at src/Framework/Constraint/Object/ObjectEquals.php:84
protected function matches(mixed $other): bool
{
if (!is_object($other)) {
throw new ActualValueIsNotAnObjectException;
}
$object = new ReflectionObject($other);
if (!$object->hasMethod($this->method)) {
throw new ComparisonMethodDoesNotExistException(
$other::class,
$this->method,
);
}
$method = $object->getMethod($this->method);
if (!$method->hasReturnType()) {
throw new ComparisonMethodDoesNotDeclareBoolReturnTypeException(
$other::class,
$this->method,
);
}
$returnType = $method->getReturnType();
if (!$returnType instanceof ReflectionNamedType) {
throw new ComparisonMethodDoesNotDeclareBoolReturnTypeException(
$other::class,
$this->method,
);
}
if ($returnType->allowsNull()) {
throw new ComparisonMethodDoesNotDeclareBoolReturnTypeException(
$other::class,
$this->method,View on GitHub (pinned to f123cdb2a2)