sebastianbergmann/comparator · error · ComparisonFailure

Failed asserting that two values of enumeration

Error message

Failed asserting that two values of enumeration %s are equal, %s does not match expected %s.

What it means

sebastian/comparator's EnumerationComparator compares two PHP 8.1+ UnitEnum cases. It throws a ComparisonFailure when both values are cases of the same enum class but are not the identical case (===). This surfaces in PHPUnit as a failed assertion when two enum values differ.

Solutions

  1. Inspect the assertion diff for the actual case name reported in the message and fix the code under test to return the expected enum case
  2. Update the test's expected enum case if the new behavior is correct
  3. If the enum cases should be considered equivalent, compare on a property/backing value instead of case identity, or register a custom comparator

Example fix

// before
$this->assertEquals(Status::Active, $service->statusFor($user));
// ComparisonFailure: Status::Suspended does not match expected Status::Active
// after
$this->assertEquals(Status::Active, $service->activate($user)); // fix code or update expected case
Defensive patterns

Strategy: validation

Validate before calling

if (!$a instanceof Suit || !$b instanceof Suit) throw new InvalidArgumentException('Both values must be Suit enum cases');
if ($a !== $b) { /* handle mismatch before asserting */ }

Type guard

function isSuit(mixed $v): bool { return $v instanceof Suit; }

Prevention

When it happens

Trigger: Calling ComparatorFactory->getComparatorFor(...)->assertEquals($expected, $actual) (or a PHPUnit assertion like assertEquals/assertSame on enum values) where $expected and $actual are different cases of the same enum class, e.g. Suit::Hearts vs Suit::Spades.

Common situations: Unit tests where a function under test returns a different enum case than expected after a refactor or a mapping/lookup table change; comparing enums whose cases were renamed or re-ordered; asserting a default enum value that changed between library versions.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of sebastianbergmann/comparator@00837a9d22 (2026-09-15). Data as JSON: /api/errors/e16f188b7a8d394c. Report an issue: GitHub.

Appendix: source

Thrown at src/EnumerationComparator.php:46

    {
        return $expected instanceof UnitEnum &&
               $actual instanceof UnitEnum &&
               $expected::class === $actual::class;
    }

    /**
     * @throws ComparisonFailure
     */
    public function assertEquals(mixed $expected, mixed $actual, float $delta = 0.0, bool $canonicalize = false, bool $ignoreCase = false): void
    {
        assert($expected instanceof UnitEnum);
        assert($actual instanceof UnitEnum);

        if ($expected === $actual) {
            return;
        }

        throw new ComparisonFailure(
            $expected,
            $actual,
            '',
            '',
            sprintf(
                'Failed asserting that two values of enumeration %s are equal, %s does not match expected %s.',
                $expected::class,
                $actual->name,
                $expected->name,
            ),
            $this->contextLines(),
        );
    }
}

View on GitHub (pinned to 00837a9d22)