sebastianbergmann/phpunit · error · ComparisonMethodDoesNotAcceptParameterTypeException

%s is not an accepted argument type for comparison method %s

Error message

%s is not an accepted argument type for comparison method %s::%s().

What it means

The final precondition of assertObjectEquals(): PHPUnit takes the declared parameter type of the comparison method (resolving 'self' to the actual class) and requires the EXPECTED object passed to the assertion to be an instance of it, since it will be passed as the argument. If the expected object's class does not satisfy the parameter type, this exception is thrown instead of a type error at call time.

Source

Thrown at src/Framework/Constraint/Object/ObjectEquals.php:148

        $type = $parameter->getType();

        if (!$type instanceof ReflectionNamedType) {
            throw new ComparisonMethodDoesNotDeclareParameterTypeException(
                $other::class,
                $this->method,
            );
        }

        $typeName = $type->getName();

        if ($typeName === 'self') {
            // @codeCoverageIgnoreStart
            $typeName = $other::class;
            // @codeCoverageIgnoreEnd
        }

        if (!$this->expected instanceof $typeName) {
            throw new ComparisonMethodDoesNotAcceptParameterTypeException(
                $other::class,
                $this->method,
                $this->expected::class,
            );
        }

        /** @phpstan-ignore method.dynamicName */
        $result = $other->{$this->method}($this->expected);

        assert(is_bool($result));

        return $result;
    }

    protected function failureDescription(mixed $other): string
    {
        return $this->toString();
    }

View on GitHub (pinned to f123cdb2a2)

Solutions

  1. Make the expected object an instance of the type the comparison method accepts (usually the same class as actual): build the fixture with the same class
  2. If cross-class comparison is intended, widen the parameter type on equals() to a shared interface and ensure the expected object implements it
  3. Check you have not swapped the arguments: assertObjectEquals($expected, $actual, ...)

Example fix

// before
$expected = new BaseMoney(500, 'EUR');   // BaseMoney
$actual   = new PaidMoney(500, 'EUR');    // subclass, equals(PaidMoney $other)
$this->assertObjectEquals($expected, $actual);

// after
$expected = new PaidMoney(500, 'EUR');
$actual   = new PaidMoney(500, 'EUR');
$this->assertObjectEquals($expected, $actual);
Defensive patterns

Strategy: validation

Validate before calling

// Ensure the expected object satisfies the comparator's parameter type BEFORE asserting:
$param   = (new ReflectionObject($actual))->getMethod('equals')->getParameters()[0];
$type    = $param->getType()->getName();
$type    = $type === 'self' ? $actual::class : $type;

if (!$expected instanceof $type) {
    $this->markTestIncomplete(
        sprintf('Expected must be %s, got %s', $type, $expected::class)
    );
}
$this->assertObjectEquals($expected, $actual);

Prevention

When it happens

Trigger: assertObjectEquals($expected, $actual) where $actual's equals() accepts self/SomeClass but $expected is of a different class — e.g. expected is a parent class instance, a sibling subclass, a mock/stub, or an entirely different DTO that happens to be structurally equal.

Common situations: Comparing a base-class fixture against a subclass actual; comparing a named vs anonymous/other-library representation of the same value; expected value replaced with a PHPUnit mock or prophecy stub of an unrelated interface; typo passing arguments swapped (expected/actual of different types).

Related errors


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