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
- 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
- Update the test's expected enum case if the new behavior is correct
- 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
- Use assertSame/assertEquals on enum cases only when identity is intended; otherwise compare ->name or backing values
- Keep enum case names stable or grep tests when renaming cases
- Let the type system help: parameter-hint the enum so wrong cases fail at call time
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
- Failed asserting that two Number objects are equal.
- Failed asserting that
- is not instance of expected class " ".
- Failed asserting that two arrays are equal.
- Failed asserting that closure declared at
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)