{"record":{"id":"77df551eb57f980e","repo":"sebastianbergmann/phpunit","slug":"comparison-method-s-s-does-not-declare-exactl","errorCode":null,"errorMessage":"Comparison method %s::%s() does not declare exactly one parameter.","messagePattern":"Comparison method (.+?)::(.+?)\\(\\) does not declare exactly one parameter\\.","errorType":"exception","errorClass":"ComparisonMethodDoesNotDeclareExactlyOneParameterException","httpStatus":null,"severity":"error","filePath":"src/Framework/Constraint/Object/ObjectEquals.php","lineNumber":114,"sourceCode":"            );\n        }\n\n        if ($returnType->allowsNull()) {\n            throw new ComparisonMethodDoesNotDeclareBoolReturnTypeException(\n                $other::class,\n                $this->method,\n            );\n        }\n\n        if ($returnType->getName() !== 'bool') {\n            throw new ComparisonMethodDoesNotDeclareBoolReturnTypeException(\n                $other::class,\n                $this->method,\n            );\n        }\n\n        if ($method->getNumberOfParameters() !== 1 || $method->getNumberOfRequiredParameters() !== 1) {\n            throw new ComparisonMethodDoesNotDeclareExactlyOneParameterException(\n                $other::class,\n                $this->method,\n            );\n        }\n\n        assert(count($method->getParameters()) > 0);\n        $parameter = $method->getParameters()[0];\n\n        if (!$parameter->hasType()) {\n            throw new ComparisonMethodDoesNotDeclareParameterTypeException(\n                $other::class,\n                $this->method,\n            );\n        }\n\n        $type = $parameter->getType();\n\n        if (!$type instanceof ReflectionNamedType) {","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/sebastianbergmann/phpunit/blob/f123cdb2a2d49f15025794166cfed8bda8627dd2/src/Framework/Constraint/Object/ObjectEquals.php#L96-L132","documentation":"The comparison method used by assertObjectEquals() must declare exactly one parameter, and that parameter must be required (no default). PHPUnit reflects the method and throws this exception when getNumberOfParameters() or getNumberOfRequiredParameters() differs from 1, because the constraint calls it as `$other->equals($expected)` with exactly one argument.","triggerScenarios":"equals() declared with zero parameters (`public function equals(): bool`), with two or more parameters, or with one optional parameter having a default value (`public function equals(self $other = null): bool`); also variadic signatures `equals(self ...$others)`.","commonSituations":"Java-ported equals(mixed $other = null) with a nullable default; 'fluent' comparison APIs like equals($other, $strict = true); stateless helpers that compare against an injected field and take no argument.","solutions":["Declare exactly one required typed parameter: `public function equals(self $other): bool`","Move extra options into the method's behavior or separate methods (equalsStrict()) and pass that name to assertObjectEquals()","If a no-arg comparator compares against an internal expected value, restructure the test to use assertThat($actual->value(), $this->equalTo($expectedValue))"],"exampleFix":"// before\nclass Money\n{\n    public function equals(self $other = null, bool $strict = true): bool { ... }\n}\n$this->assertObjectEquals($expected, $actual);\n\n// after\nclass Money\n{\n    public function equals(self $other): bool { ... }\n}\n$this->assertObjectEquals($expected, $actual);","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"function comparisonMethodTakesExactlyOneRequiredParameter(object $actual, string $method = 'equals'): bool\n{\n    $m = (new ReflectionObject($actual))->getMethod($method);\n    return $m->getNumberOfParameters() === 1\n        && $m->getNumberOfRequiredParameters() === 1;\n}","tryCatchPattern":null,"preventionTips":["Comparator signature is fixed: exactly one required parameter — no defaults, no variadics, no extra flags","Move strictness/strategy options into separate method names (equalsStrict()) passed to assertObjectEquals()"],"tags":["php","phpunit","assertobjectequals","method-signature","equals-method"],"backgroundTag":"equals-method-contract-violation","analyzedSha":"f123cdb2a2d49f15025794166cfed8bda8627dd2","analyzedAt":"2026-08-23T01:20:58.058Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}