Java library for verifying the contract of equals and hashCode methods in unit tests
—
Core functionality for verifying equals and hashCode contracts for individual classes. The SingleTypeEqualsVerifierApi provides extensive configuration options for field handling, warning suppression, and inheritance scenarios.
Creates a verifier for testing a single class with EqualsVerifier.
/**
* Factory method for general use
* @param type The class for which the equals method should be tested
* @return A fluent API for EqualsVerifier
*/
public static <T> SingleTypeEqualsVerifierApi<T> forClass(Class<T> type);Usage Examples:
import nl.jqno.equalsverifier.EqualsVerifier;
// Basic verification
EqualsVerifier.forClass(Person.class).verify();
// With configuration
EqualsVerifier.forClass(Person.class)
.suppress(Warning.STRICT_INHERITANCE)
.verify();Creates a pre-configured verifier that works with most IDE-generated equals and hashCode methods.
/**
* Creates a configuration object that is pre-configured so that it can be used with most
* IDE-generated equals and hashCode methods without any further configuration
* @return A reusable configuration object with a fluent API
*/
public static ConfiguredEqualsVerifier simple();Usage Examples:
// Pre-configured for IDE-generated methods
EqualsVerifier.simple()
.forClass(Person.class)
.verify();
// Automatically suppresses STRICT_INHERITANCE and NONFINAL_FIELDS warningsSuppresses specific warnings that may not apply to your use case.
/**
* Suppresses warnings given by EqualsVerifier
* @param warnings A list of warnings to suppress in EqualsVerifier
* @return this, for easy method chaining
*/
public SingleTypeEqualsVerifierApi<T> suppress(Warning... warnings);Usage Examples:
EqualsVerifier.forClass(Person.class)
.suppress(Warning.STRICT_INHERITANCE, Warning.NONFINAL_FIELDS)
.verify();Adds prefabricated values for classes that EqualsVerifier cannot instantiate automatically.
/**
* Adds prefabricated values for instance fields of classes that EqualsVerifier cannot
* instantiate by itself
* @param otherType The class of the prefabricated values
* @param red An instance of S
* @param blue Another instance of S, not equal to red
* @return this, for easy method chaining
* @throws NullPointerException If either otherType, red, or blue is null
* @throws IllegalArgumentException If red equals blue
*/
public <S> SingleTypeEqualsVerifierApi<T> withPrefabValues(
Class<S> otherType,
S red,
S blue
);
/**
* Adds prefabricated values for instance fields with a given name that EqualsVerifier
* cannot instantiate by itself
* @param fieldName The name of the field that the prefabricated values are linked to
* @param red An instance of S
* @param blue Another instance of S, not equal to red
* @return this, for easy method chaining
* @throws NullPointerException If red or blue is null, or if the named field does not exist in the class
* @throws IllegalArgumentException If red equals blue
*/
public <S> SingleTypeEqualsVerifierApi<T> withPrefabValuesForField(
String fieldName,
S red,
S blue
);Usage Examples:
// Global prefab values for a type
EqualsVerifier.forClass(Person.class)
.withPrefabValues(Address.class, redAddress, blueAddress)
.verify();
// Field-specific prefab values
EqualsVerifier.forClass(Person.class)
.withPrefabValuesForField("specialField", redValue, blueValue)
.verify();Adds factories for generating prefab values for generic classes.
/**
* Adds a factory to generate prefabricated values for instance fields of classes with 1 generic
* type parameter that EqualsVerifier cannot instantiate by itself
* @param otherType The class of the prefabricated values
* @param factory A factory to generate an instance of S, given a value of its generic type parameter
* @return this, for easy method chaining
* @throws NullPointerException if either otherType or factory is null
*/
public <S> SingleTypeEqualsVerifierApi<T> withGenericPrefabValues(
Class<S> otherType,
Func1<?, S> factory
);
/**
* Adds a factory to generate prefabricated values for instance fields of classes with 2 generic
* type parameters that EqualsVerifier cannot instantiate by itself
* @param otherType The class of the prefabricated values
* @param factory A factory to generate an instance of S, given values of its generic type parameters
* @return this, for easy method chaining
* @throws NullPointerException if either otherType or factory is null
*/
public <S> SingleTypeEqualsVerifierApi<T> withGenericPrefabValues(
Class<S> otherType,
Func2<?, ?, S> factory
);Usage Examples:
// Factory for generic class with one type parameter
EqualsVerifier.forClass(Container.class)
.withGenericPrefabValues(Optional.class, Optional::of)
.verify();
// Factory for generic class with two type parameters
EqualsVerifier.forClass(Container.class)
.withGenericPrefabValues(Map.class, (k, v) -> Map.of(k, v))
.verify();Controls which fields are included or excluded from equals contract verification.
/**
* Signals that all given fields are not relevant for the equals contract
* @param fields Fields that should be ignored
* @return this, for easy method chaining
*/
public SingleTypeEqualsVerifierApi<T> withIgnoredFields(String... fields);
/**
* Signals that only the given fields are relevant for the equals contract
* @param fields Fields that should be included
* @return this, for easy method chaining
*/
public SingleTypeEqualsVerifierApi<T> withOnlyTheseFields(String... fields);
/**
* Signals that certain fields can never be null
* @param fields Fields that can never be null
* @return this, for easy method chaining
*/
public SingleTypeEqualsVerifierApi<T> withNonnullFields(String... fields);Usage Examples:
// Ignore specific fields
EqualsVerifier.forClass(Person.class)
.withIgnoredFields("id", "lastModified")
.verify();
// Only test specific fields
EqualsVerifier.forClass(Person.class)
.withOnlyTheseFields("firstName", "lastName", "email")
.verify();
// Mark fields as non-null
EqualsVerifier.forClass(Person.class)
.withNonnullFields("firstName", "lastName")
.verify();Configures verification behavior for inheritance hierarchies.
/**
* Signals that getClass is used in the implementation of the equals method,
* instead of an instanceof check
* @return this, for easy method chaining
*/
public SingleTypeEqualsVerifierApi<T> usingGetClass();
/**
* Signals inheritance hierarchy with overridden equals in superclass
* @return this, for easy method chaining
*/
public SingleTypeEqualsVerifierApi<T> withRedefinedSuperclass();
/**
* Provides reference to subclass with overridden equals
* @param subclass Reference to a subclass of T for which no instance can be equal to any instance of T
* @return this, for easy method chaining
*/
public SingleTypeEqualsVerifierApi<T> withRedefinedSubclass(Class<? extends T> subclass);Usage Examples:
// For classes using getClass() instead of instanceof
EqualsVerifier.forClass(Person.class)
.usingGetClass()
.verify();
// For inheritance hierarchies
EqualsVerifier.forClass(Person.class)
.withRedefinedSuperclass()
.withRedefinedSubclass(Employee.class)
.verify();Configures verification for classes with cached hashCode implementations.
/**
* Configures cached hashCode verification
* @param cachedHashCodeField Name of field that caches the hashCode
* @param calculateHashCodeMethod Name of method that calculates the hashCode
* @param example An instance of T with cached hashCode properly initialized
* @return this, for easy method chaining
*/
public SingleTypeEqualsVerifierApi<T> withCachedHashCode(
String cachedHashCodeField,
String calculateHashCodeMethod,
T example
);
/**
* Configures Lombok cached hashCode verification
* @param example An instance of T with cached hashCode properly initialized
* @return this, for easy method chaining
*/
public SingleTypeEqualsVerifierApi<T> withLombokCachedHashCode(T example);Usage Examples:
// Custom cached hashCode
Person example = new Person("John", "Doe");
example.hashCode(); // Initialize cache
EqualsVerifier.forClass(Person.class)
.withCachedHashCode("cachedHashCode", "calculateHashCode", example)
.verify();
// Lombok cached hashCode
Person lombokExample = new Person("John", "Doe");
lombokExample.hashCode(); // Initialize cache
EqualsVerifier.forClass(Person.class)
.withLombokCachedHashCode(lombokExample)
.verify();Configures how annotations are handled during verification.
/**
* Ignores specified annotations during verification
* @param annotations Annotation classes to ignore
* @return this, for easy method chaining
*/
public SingleTypeEqualsVerifierApi<T> withIgnoredAnnotations(Class<?>... annotations);
/**
* Determines how a getter name can be derived from a field name
* @param converter A function that converts from field name to getter name
* @return this, for easy method chaining
*/
public SingleTypeEqualsVerifierApi<T> withFieldnameToGetterConverter(
Function<String, String> converter
);Usage Examples:
// Ignore specific annotations
EqualsVerifier.forClass(Person.class)
.withIgnoredAnnotations(Generated.class, SuppressWarnings.class)
.verify();
// Custom getter naming convention
EqualsVerifier.forClass(Person.class)
.withFieldnameToGetterConverter(field -> "retrieve" +
field.substring(0, 1).toUpperCase() + field.substring(1))
.verify();Methods to execute the verification and get results.
/**
* Performs verification and throws AssertionError on failure
* @throws AssertionError if the equals and/or hashCode contract is violated
* @throws NullPointerException if required parameters are null
*/
public void verify();
/**
* Performs verification and returns report with results
* @return EqualsVerifierReport with verification results
*/
public EqualsVerifierReport report();
/**
* Performs verification and returns report with URL control
* @param showUrl Whether to include URL in error messages
* @return EqualsVerifierReport with verification results
*/
public EqualsVerifierReport report(boolean showUrl);Usage Examples:
// Basic verification (throws on failure)
EqualsVerifier.forClass(Person.class).verify();
// Report-based verification
EqualsVerifierReport report = EqualsVerifier.forClass(Person.class).report();
if (!report.isSuccessful()) {
System.err.println("Verification failed: " + report.getMessage());
}
// Report with URL control
EqualsVerifierReport reportWithoutUrl = EqualsVerifier.forClass(Person.class)
.report(false);Install with Tessl CLI
npx tessl i tessl/maven-nl-jqno-equalsverifier--equalsverifier