All 15 equals(), hashCode() & toString() Contracts questions
More in equals(), hashCode() & toString() Contracts
Advertisement
Back to results for “Applications”
Java › equals(), hashCode() & toString() Contracts

How would you write a unit test that thoroughly verifies a custom equals() and hashCode() implementation satisfies its contract, and what testing libraries exist specifically for this purpose?

Intermediate

Answer

A thorough test suite should verify: reflexivity (x.equals(x)), symmetry (x.equals(y) implies y.equals(x)), consistency across multiple calls, correct handling of null and unrelated-type comparisons (both should return false, never throw), that equal objects produce identical hashCode() values, and ideally that meaningfully different field values correctly produce inequality -- rather than hand-writing all these checks manually and risking missing an edge case, the widely-used EqualsVerifier library automates comprehensive contract verification for a class's equals()/hashCode() implementation with a single fluent assertion, catching subtle violations (like forgetting a field, or a mutable-field risk) that manual tests might easily overlook.
// Using EqualsVerifier (a popular open-source testing library) for comprehensive automatic verification
import nl.jqno.equalsverifier.EqualsVerifier;

@Test
void equalsContract() {
    EqualsVerifier.forClass(Point.class).verify();
    // automatically checks reflexivity, symmetry, transitivity, null-safety,
    // hashCode consistency, and more -- catches subtle bugs a hand-written test might miss
}
Real-world example A team adopts EqualsVerifier across their domain model classes, catching a previously-unnoticed bug where a Money class's equals() compared the amount field but its hashCode() forgot to include the currency field, a subtle contract violation their existing hand-written unit tests hadn't happened to catch.

Common follow-ups: What specific configuration options does EqualsVerifier provide for classes with intentionally non-standard equals() behavior (like inheritance-based comparison)?;How would you write these contract verification tests manually without a library, and what's the risk of missing an edge case that way?