### Main module-info.java example Source: https://jqno.nl/equalsverifier/manual/jpms This is an example of a module-info.java file for your main source set. ```java module my.module { exports my.module; } ``` -------------------------------- ### Verify Class with Examples Source: https://jqno.nl/equalsverifier/manual/prefab-values Use `forExamples` to provide instances of a class. EqualsVerifier will use these instances to infer prefab values and verify that all fields are different between the provided examples. ```java var red = new Book("Don Quixote", new Person("Cervantes", 1547)); var blue = new Book("Hitch-Hiker's Guide to the Galaxy", new Person("Douglas Adams", 1952)); // Let's assume both authors were married and their `marriedTo` field is correctly initialized EqualsVerifier.forExamples(red, blue) .verify(); ``` -------------------------------- ### Bypass cached hashCode example requirement Source: https://jqno.nl/equalsverifier/manual/caching-hashcodes Use this approach when constructing an example instance is difficult, requiring the suppression of a specific warning. ```java EqualsVerifier.forClass(ObjectWithCachedHashCode.class) .withCachedHashCode("cachedHashCode", "calcHashCode", null) .suppress(Warning.NO_EXAMPLE_FOR_CACHED_HASHCODE) .verify(); ``` -------------------------------- ### Analyze dependency tree output Source: https://jqno.nl/equalsverifier/errormessages/unsupported-class-file-major-version Example output from a Maven dependency tree showing conflicting versions of Byte Buddy. ```text [INFO] +- org.springframework.boot:spring-boot-starter-test:jar:2.4.3:test [INFO] | +- org.mockito:mockito-core:jar:3.6.28:test [INFO] | | \- net.bytebuddy:byte-buddy-agent:jar:1.10.20:test [...] [INFO] +- nl.jqno.equalsverifier:equalsverifier:jar:3.12:test [INFO] | +- org.objenesis:objenesis:jar:3.3:test [INFO] | \- net.bytebuddy:byte-buddy:jar:1.10.20:test ``` -------------------------------- ### Implement equals using getClass Source: https://jqno.nl/equalsverifier/errormessages/subclass-object-is-not-equal-to-an-instance-of-a-trivial-subclass-with-equal-fields Example of an equals implementation that triggers the subclass equality error. ```java public boolean equals(Object other) { if (other == null || !getClass().equals(other.getClass())) { return false; } // ... } ``` -------------------------------- ### Demonstrate getClass() behavior with subclasses Source: https://jqno.nl/equalsverifier/manual/instanceof-or-getclass Example showing how getClass() returns false when comparing a base class instance to a subclass instance. ```java class Foo { private final int i; // ... } class SubFoo extends Foo {} Foo a = new Foo(); Foo b = new SubFoo(); System.out.println(a.equals(b)); ``` -------------------------------- ### Kotlin Delegation Example Source: https://jqno.nl/equalsverifier/manual/kotlin Illustrates Kotlin delegation fields as seen by EqualsVerifier. Requires `org.jetbrains.kotlin:kotlin-reflect` for proper handling and translation of field names. ```kotlin data class StringContainer(s: String) class Foo(container: StringContainer) { private val bar: String by container::s // object delegation private val baz: String by lazy { ... } // lazy delegation } ``` -------------------------------- ### Implement non-standard equals method Source: https://jqno.nl/equalsverifier/errormessages/coverage-is-not-100-percent This example demonstrates an equals method with a conditional branch that EqualsVerifier cannot fully exercise due to the state space size. ```java @Override public boolean equals(Object obj) { if (!(obj instanceof Point)) { return false; } if (x == 42) { return false; } Point other = (Point)obj; return x == other.x && y == other.y; } ``` -------------------------------- ### Example Maven Dependency Tree Output Source: https://jqno.nl/equalsverifier/errormessages/byte-buddy This output illustrates a common scenario where a dependency like Spring Boot Starter Test transitively includes an older version of Byte Buddy, potentially conflicting with the version required by EqualsVerifier. ```text [INFO] +- org.springframework.boot:spring-boot-starter-test:jar:2.4.3:test [INFO] | +- org.mockito:mockito-core:jar:3.6.28:test [INFO] | | \- net.bytebuddy:byte-buddy-agent:jar:1.10.20:test [INFO] \- nl.jqno.equalsverifier:equalsverifier:jar:3.12:test [INFO] | +- org.objenesis:objenesis:jar:3.3:test [INFO] | \- net.bytebuddy:byte-buddy:jar:1.10.20:test ``` -------------------------------- ### Basic EqualsVerifier Usage Source: https://jqno.nl/equalsverifier/manual/prefab-values This is a basic example of how to use EqualsVerifier to verify the `equals()` and `hashCode()` methods of a class. Ensure the class has a proper constructor and equals/hashCode implementations. ```java class Book { private final String title; private final Person author; // Constructor, equals(), hashCode() omitted } EqualsVerifier.forClass(Book.class) .verify(); ``` -------------------------------- ### Error message for missing factory Source: https://jqno.nl/equalsverifier/manual/final-means-final Example of the error message displayed when EqualsVerifier fails to instantiate a class. ```text -> Cannot instantiate NonConstructableParent. Use #withFactory() so EqualsVerifier can construct NonConstructableParent instances without using reflection. ``` -------------------------------- ### Error Message for Missing Factory Source: https://jqno.nl/equalsverifier/manual/final-means-final Example of the error message displayed when a factory is required but not provided. ```text -> Cannot instantiate a subclass of NonConstructableSuper (attempted subclass: NonConstructableSubForNonConstructableSuper). Use the overload of #withRedefinedSubclass() to specify a subclass. ``` -------------------------------- ### Record Constructor with Value Check Source: https://jqno.nl/equalsverifier/errormessages/record-failed-to-run-constructor Example of a Java record with a constructor that enforces a minimum value for a primitive field. ```java public record Foo(int i) { public Foo { if (i < 42) { throw new IllegalArgumentException(); } } } ``` -------------------------------- ### Implement hashCode for Interval class Source: https://jqno.nl/equalsverifier/errormessages/significant-fields-equals-relies-on-foo-but-hashcode-does-not Example of a hashCode implementation that may cause collisions if fields have identical values. ```java @Override public int hashCode() { return start.hashCode() ^ end.hashCode(); } ``` -------------------------------- ### Implement Lombok cached hash code Source: https://jqno.nl/equalsverifier/errormessages/significant-fields-equals-relies-on-foo-but-hashcode-does-not Example of a class using Lombok's @EqualsAndHashCode with lazy caching. ```java @RequiredArgsConstructor @EqualsAndHashCode(cacheStrategy = EqualsAndHashCode.CacheStrategy.LAZY) public class CachedHashCode { private final String foo; } ``` -------------------------------- ### Implement a class with a cached hashCode Source: https://jqno.nl/equalsverifier/manual/caching-hashcodes Example of a class structure where the hashCode is calculated once and stored in a final field. ```java class ObjectWithCachedHashCode { private final String name; private final int cachedHashCode; public ObjectWithCachedHashCode(String name) { this.name = name; this.cachedHashCode = calcHashCode(); } @Override public final int hashCode() { return cachedHashCode; } private int calcHashCode() { return name.hashCode(); } // equals method elided for brevity } ``` -------------------------------- ### Record Constructor with Null Check Source: https://jqno.nl/equalsverifier/errormessages/record-failed-to-run-constructor Example of a Java record with a constructor that enforces non-null fields. ```java public record Foo(String s) { public Foo { Objects.requireNonNull(s); } } ``` -------------------------------- ### Using prefab values for inaccessible dependencies Source: https://jqno.nl/equalsverifier/manual/jpms When a class or its dependencies are inaccessible via the Java Module System, provide prefab values for those types to EqualsVerifier. This example shows how to provide prefab values for a 'Bar' class. ```java import my.module.package.somewhere.inaccessible.Bar; EqualsVerifier.forClass(Foo.class) .withPrefabValues(Bar.class, new Bar(1), new Bar(2)) .verify(); ``` -------------------------------- ### Verify Mockito Mock Equality Source: https://jqno.nl/equalsverifier/manual/prefab-values This example demonstrates the expected behavior of Mockito mocks: two different mocks of the same type should not be equal and should have different hash codes. This is a caveat for EqualsVerifier's Mockito integration. ```java var red = mock(Person.class); var blue = mock(Person.class); assertFalse(red.equals(blue)); ``` -------------------------------- ### Kotlin Interface Delegation Example Source: https://jqno.nl/equalsverifier/manual/kotlin Demonstrates interface delegation in Kotlin. The delegated instance is stored in a field like `$$delegate_0`, and EqualsVerifier may require prefab values for the delegated type. ```kotlin interface Foo { val foo: Int } data class FooImpl(override val foo: Int) : Foo class InterfaceDelegation(fooValue: Int) : Foo by FooImpl(fooValue) { override fun equals(other: Any?): Boolean = (other is InterfaceDelegation) && foo == other.foo override fun hashCode(): Int = foo } ``` -------------------------------- ### Custom Field to Getter Conversion Source: https://jqno.nl/equalsverifier/manual/jpa-entities Use when your project has a custom convention for naming getters based on field names. This example shows how to convert a field name like 'm_employee' to a getter 'getEmployee()'. ```java EqualsVerifier .forClass(Foo.class) .withFieldnameToGetterConverter( fn -> "get" + Character.toUpperCase(fn.charAt(2)) + fn.substring(3) ) .verify(); ``` -------------------------------- ### Basic EqualsVerifier Test Source: https://jqno.nl/equalsverifier/manual/getting-started Use this basic setup in your test class to verify the equals() contract for a given class. EqualsVerifier is strict by default. ```java import nl.jqno.equalsverifier.*; @Test public void equalsContract() { EqualsVerifier.forClass(Foo.class) .verify(); } ``` -------------------------------- ### Kotlin Data Class Example Source: https://jqno.nl/equalsverifier/manual/kotlin Demonstrates how EqualsVerifier ignores properties not defined in the primary constructor for Kotlin data classes. Requires `org.jetbrains.kotlin:kotlin-reflect`. ```kotlin data class MyDataclass(val value: String) { val isEmpty = value.isEmpty() } ``` -------------------------------- ### Define a class with relaxed equality Source: https://jqno.nl/equalsverifier/manual/relaxed-equality An example of a Rational class where equality is determined by the result of division rather than individual field values. ```java class Rational { private final int numerator; private final int denominator; public equals(Object obj) { if (!(obj instanceof Rational)) { return false; } Rational other = (Rational)obj; return (numerator / denominator) == (other.numerator / other.denominator); // awfully bad implementation but you get the idea } // leaving out everything else for brevity } ``` -------------------------------- ### Example of an incorrect equals method Source: https://jqno.nl/equalsverifier/faq This snippet demonstrates a flawed equals implementation that could potentially bypass EqualsVerifier's checks. ```java public boolean equals(Object obj) { if (!(obj instanceof Synonym)) { return false; } Synonym other = (Synonym)obj; if ("equality".equals(word) && "sameness".equals(other.word)) { return true; } return word.equals(other.word); } ``` -------------------------------- ### Test cached hashCode using withCachedHashCode Source: https://jqno.nl/equalsverifier/manual/caching-hashcodes Legacy approach for testing cached hashCodes by specifying the field name, calculation method, and an example instance. ```java @Test public void testCachedHashCode() { EqualsVerifier.forClass(ObjectWithCachedHashCode.class) .withCachedHashCode("cachedHashCode", "calcHashCode", new ObjectWithCachedHashCode("something")) .verify(); } ``` -------------------------------- ### Lombok Class Example Source: https://jqno.nl/equalsverifier/errormessages/coverage-is-not-100-percent This Lombok-generated class includes null checks in its equals method, which EqualsVerifier might not cover due to @Nonnull annotations. ```java @EqualsAndHashCode public static final class Lombok { @Nonnull private final String s; public Lombok(String s) { this.s = s; } } ``` -------------------------------- ### Test for Leaf Node Equals Coverage Source: https://jqno.nl/equalsverifier/errormessages/coverage-is-not-100-percent This test setup involves creating a temporary subclass EndPoint to satisfy the canEqual check and achieve 100% coverage for the ColorPoint equals method. Ensure ColorPoint is not final to allow subclassing. ```java @Test public void leafNodeEquals() { class EndPoint extends ColorPoint { public EndPoint(int x, int y, Color color) { super(x, y, color); } @Override public boolean canEqual(Object obj) { return false; } } EqualsVerifier.forClass(ColorPoint.class) .withRedefinedSuperclass() .withRedefinedSubclass(EndPoint.class) // Don't forget to add this line .verify(); } ``` -------------------------------- ### Check dependency trees Source: https://jqno.nl/equalsverifier/errormessages/unsupported-class-file-major-version Commands to inspect the dependency hierarchy in Maven and Gradle projects to identify version conflicts. ```bash mvn dependency:tree ``` ```bash gradle dependencies ``` -------------------------------- ### Class Definition with Simple Dependencies Source: https://jqno.nl/equalsverifier/manual/prefab-values This `Book` class has fields of types `String` and `Person`. EqualsVerifier can handle `String` but may require prefab values for `Person` if `Person` itself has complex dependencies. ```java class Book { private final String title; private final Person author; // Constructor, equals(), hashCode() omitted } ``` -------------------------------- ### Instantiate classes with withFactory Source: https://jqno.nl/equalsverifier/manual/final-means-final Use withFactory to provide a custom instantiation strategy when EqualsVerifier cannot automatically construct an object. ```java class Foo { private final int i; private final String s; private final Bar b; public Foo(int i, String s, Bar b, Object hereToMakeConstructorStrategyFail) { this.i = i; this.s = s; this.b = b; } } EqualsVerifier.forClass(Foo.class) .withFactory(values -> new Foo( values.getInt("i"), values.getString("s"), values.get("b"), new Object())) .verify(); ``` -------------------------------- ### BigDecimal comparison behavior Source: https://jqno.nl/equalsverifier/errormessages/bigdecimal-equality Demonstrates the difference between compareTo and equals for BigDecimal instances. ```java BigDecimal one = new BigDecimal("1"); BigDecimal alsoOne = new BigDecimal("1.0"); // prints true - 1 is the same as 1.0 System.out.println(one.compareTo(alsoOne) == 0); // prints false - 1 is not the same as 1.0 System.out.println(one.equals(alsoOne)); ``` -------------------------------- ### Using withFactory() to Instantiate Foo Source: https://jqno.nl/equalsverifier/errormessages/cannot-instantiate-use-withfactory Use `withFactory()` when EqualsVerifier cannot instantiate a class via reflection. This method allows you to provide a factory that constructs instances of the class, passing necessary values. ```java EqualsVerifier.forClass(Foo.class) .withFactory(values -> new Foo(values.get("bar"))) .verify(); ``` -------------------------------- ### Test module-info.java for full module opening Source: https://jqno.nl/equalsverifier/manual/jpms Use this configuration in your src/test/java module-info.java to open the entire module for reflection, allowing EqualsVerifier to access all classes. This is the simplest approach. ```java open module my.module { exports my.module; requires org.junit.jupiter.api; requires nl.jqno.equalsverifier; } ``` -------------------------------- ### Check Gradle Dependencies Source: https://jqno.nl/equalsverifier/errormessages/byte-buddy Use this command to inspect your project's dependency tree and identify version conflicts. This helps in understanding which libraries are pulling in older versions of transitive dependencies. ```bash gradle dependencies ``` -------------------------------- ### Configure Factory for Non-Final Classes Source: https://jqno.nl/equalsverifier/manual/final-means-final Provides a factory to instantiate a class and a subclass when EqualsVerifier cannot generate one automatically. ```java class Foo { private final int i; public Foo(int i, Object requireFactory) { this.i = i; } } EqualsVerifier.forClass(Foo.class) .withFactory( values -> new Foo(values.getInt("i"), new Object()) values -> new Foo(values.getInt("i"), new Object()) {} ) .verify(); ``` -------------------------------- ### Example of a class causing ClassCastException Source: https://jqno.nl/equalsverifier/errormessages/classcastexception A class where type erasure causes an AtomicReference to contain an Object instead of a String, leading to a ClassCastException during verification. ```java final class StringReference { private final AtomicReference stringRef; @Override public boolean equals(Object obj) { referToGenericParameter(); if (!(obj instanceof StringReference)) { return false; } StringReference other = (StringReference)obj; return stringRef.equals(other.stringRef); } private void referToGenericParameter() { stringRef.get().length(); } } ``` -------------------------------- ### Test module-info.java for specific package opening Source: https://jqno.nl/equalsverifier/manual/jpms Configure your src/test/java module-info.java to open only specific packages for reflection. This provides more granular control over access. ```java module my.module { exports my.module; opens my.module.package.model; requires org.junit.jupiter.api; requires nl.jqno.equalsverifier; } ``` -------------------------------- ### Maven dependency management configuration Source: https://jqno.nl/equalsverifier/errormessages/noclassdeffounderror Add this to your pom.xml to force the correct version of cglib-nodep. ```xml cglib cglib-nodep 2.2 ``` -------------------------------- ### Configure EqualsVerifier with a Configuration Object Source: https://jqno.nl/equalsverifier/manual/several-classes-at-once For complex configurations like ignored fields or redefined subclasses, use `EqualsVerifier.configure()` to create a reusable configuration object. This reduces boilerplate when testing multiple classes with similar settings. ```java ConfiguredEqualsVerifier ev = EqualsVerifier.configure().usingGetClass(); ev.forClass(Student.class) .withIgnoredFields("grade") .verify(); ev.forClass(Teacher.class) .withIgnoredFields("salary") .verify(); ev.forClass(Staff.class) .withRedefinedSubclass(Janitor.class) .verify(); ``` -------------------------------- ### Provide Prefab Values for Record Fields Source: https://jqno.nl/equalsverifier/errormessages/record-failed-to-run-constructor If a record's constructor rejects specific values (e.g., prefab values like 1 or 2 for integers), provide custom prefab values. ```java EqualsVerifier.forClass(Foo.class) .withPrefabValues(int.class, 42, 1337) .verify(); ``` -------------------------------- ### JPA Entity with Business Key and Non-Persisted State Source: https://jqno.nl/equalsverifier/manual/jpa-entities Example of a custom equals method for a JPA entity with a business key, where equality is based on a field if the object hasn't been persisted yet. ```java @Override public boolean equals(Object obj) { if (!(obj instanceof Foo)) { return false; } Foo other = (Foo)obj; if (id == 0L && other.id == 0L) { return false; } return Objects.equals(someField, other.someField); } ``` -------------------------------- ### Custom Equals and HashCode for JPA Entities Source: https://jqno.nl/equalsverifier/manual/jpa-entities Example of a custom equals method for a JPA entity that considers fields only if the object hasn't been persisted yet. If persisted, it uses the id for comparison. ```java @Override public boolean equals(Object obj) { if (!(obj instanceof Foo)) { return false; } Foo other = (Foo)obj; if (id == 0L && other.id == 0L) { return false; } return id == other.id; } ``` -------------------------------- ### Implement equals using instanceof Source: https://jqno.nl/equalsverifier/errormessages/subclass-object-is-not-equal-to-an-instance-of-a-trivial-subclass-with-equal-fields Recommended fix for framework-generated proxies to ensure equality with subclasses. ```java public boolean equals(Object other) { if (!(other instanceof Foo)) { return false; } // ... } ``` -------------------------------- ### Verify Kotlin Class with Delegates and Prefab Values Source: https://jqno.nl/equalsverifier/manual/kotlin Use this to verify Kotlin classes with delegates, providing prefab values for fields. Note that reflexivity checks may not work for delegates. ```kotlin EqualsVerifier.forClass(Foo::class.java) .withPrefabValuesForField(Foo::bar.name, StringContainer("a"), StringContainer("b")) .withPrefabValuesForField(Foo::baz.name, lazy { "a" }, lazy { "b" }) .verify() ``` -------------------------------- ### Basic EqualsVerifier Usage Source: https://jqno.nl/equalsverifier/manual/why-what-how Use this one-liner to verify the equals() and hashCode() methods of a given class. It ensures all contract requirements are met and provides 100% coverage. ```java EqualsVerifier.forClass(Foo.class).verify(); ``` -------------------------------- ### Verify Simple Kotlin Class Source: https://jqno.nl/equalsverifier/manual/kotlin Use this to verify simple Kotlin classes. Provide EqualsVerifier with Java-style reflection types using `::class.java`. ```kotlin EqualsVerifier.forClass(Foo::class.java) .verify() ``` -------------------------------- ### Java Version Not Supported Message Source: https://jqno.nl/equalsverifier/errormessages/byte-buddy This message indicates that the current Java version is not supported by the version of Byte Buddy being used. Updating Byte Buddy or setting a specific VM property might resolve this. ```text Java 23 (67) is not supported by the current version of Byte Buddy which officially supports Java 22 (66) - update Byte Buddy or set net.bytebuddy.experimental as a VM property ``` -------------------------------- ### Configure EqualsVerifier for getClass() Source: https://jqno.nl/equalsverifier/manual/instanceof-or-getclass Use usingGetClass() when the class under test implements equals using getClass() instead of instanceof. ```java EqualsVerifier.forClass(Foo.class) .usingGetClass() .verify(); ``` -------------------------------- ### Check Maven Dependency Tree Source: https://jqno.nl/equalsverifier/errormessages/byte-buddy Use this command to inspect your project's dependency tree and identify version conflicts. This helps in understanding which libraries are pulling in older versions of transitive dependencies. ```bash mvn dependency:tree ``` -------------------------------- ### Skip Mockito and Provide Prefab Values Source: https://jqno.nl/equalsverifier/manual/prefab-values Instruct EqualsVerifier to skip Mockito integration and provide prefab values for specific types. This is useful when Mockito's default behavior is not desired or when custom prefab values are necessary. ```java EqualsVerifier.forClass(Book.class) .set(Mode.skipMockito()) .withPrefabValues(Person.class, ...) .verify(); ``` -------------------------------- ### Normalizing BigDecimal for consistent hashing Source: https://jqno.nl/equalsverifier/errormessages/bigdecimal-equality Use stripTrailingZeros to ensure consistent hashcode generation. ```java // Remove trailing zeros from the unscaled value of the // BigDecimal to yield a consistently scaled instance int consistentHashcode = Objects.hashCode(bdField.stripTrailingZeros()); ``` -------------------------------- ### Demonstrate broken symmetry with inheritance Source: https://jqno.nl/equalsverifier/manual/inheritance Shows how using 'instanceof' in an equals method can lead to broken symmetry when comparing a superclass and a subclass. ```java Point p = new Point(1, 1); ColorPoint cp = new ColorPoint(1, 1, RED); System.out.println(p.equals(cp)) // prints true System.out.println(cp.equals(p)) // prints false ``` -------------------------------- ### Simplified equals() and hashCode() contract verification Source: https://jqno.nl/equalsverifier This snippet provides a more lenient verification of the equals() and hashCode() contract. It's useful when strict adherence is not required or for simpler classes. ```java import nl.jqno.equalsverifier.*; @Test public void simpleEqualsContract() { EqualsVerifier.simple().forClass(Foo.class).verify(); } ``` -------------------------------- ### Verify equals() and hashCode() contract for a class Source: https://jqno.nl/equalsverifier Use this snippet to verify the equals() and hashCode() contract for a specific Java class. Ensure the class `Foo` is accessible. ```java import nl.jqno.equalsverifier.*; @Test public void equalsContract() { EqualsVerifier.forClass(Foo.class).verify(); } ``` -------------------------------- ### Implement equals using instanceof or getClass() Source: https://jqno.nl/equalsverifier/manual/instanceof-or-getclass Two common patterns for type checking in an equals method implementation. ```java public boolean equals(Object obj) { if (!(obj instanceof Foo)) return false; // ... } public boolean equals(Object obj) { if (obj == null || getClass() != obj.getClass()) return false; // ... } ``` -------------------------------- ### Test cached hashCode using withFactory Source: https://jqno.nl/equalsverifier/manual/caching-hashcodes Recommended approach for testing cached hashCodes by providing a factory and ignoring the cached field. ```java @Test public void testCachedHashCode() { EqualsVerifier.forClass(ObjectWithCachedHashCode.class) .withFactory(v -> new ObjectWithCachedHashCode(v.getString("name"))) .withIgnoredFields("cachedHashCode") .verify(); } ``` -------------------------------- ### Abstract Superclass with Final equals/hashCode Source: https://jqno.nl/equalsverifier/manual/jpa-entities Demonstrates an abstract superclass with final equals and hashCode methods that compare objects by their IDs. This pattern is useful for entities with common base properties. ```java @MappedSuperclass abstract class AbstractEntity { @Id @Column(...) private Long id; public Long getId() { return id; } @Override public final boolean equals(Object obj) { if (!(obj instanceof AbstractEntity)) { return false; } return Objects.equals(getId(), ((AbstractEntity)obj).getId()); } @Override public final int hashCode() { return Objects.hashCode(getId()); } } @Entity class Foo extends AbstractEntity { @Column(...) private String name; } ``` -------------------------------- ### Test All Classes in a Package with EqualsVerifier Source: https://jqno.nl/equalsverifier/manual/several-classes-at-once Use `EqualsVerifier.forPackage()` to test all classes within a specified package. This is useful for large domains where many classes have `equals` methods to verify. ```java EqualsVerifier.forPackage("com.example.app.domain") .verify(); ``` -------------------------------- ### Provide Prefab Values for All Integers Source: https://jqno.nl/equalsverifier/manual/prefab-values When dealing with internal invariants, provide custom prefab values for a primitive type like `int`. These values will be used for all fields of that type within the class being verified. ```java EqualsVerifier.forClass(Adult.class) .withPrefabValues(int.class, 21, 99) .verify(); ``` -------------------------------- ### Class Definition with Simple Dependencies Source: https://jqno.nl/equalsverifier/manual/prefab-values This `Person` class has fields of types `String` and `int`, which EqualsVerifier can instantiate by itself. No prefab values are needed for these types. ```java class Person { private final String name; private final int yearOfBirth; // Constructor, equals(), hashCode() omitted } ``` -------------------------------- ### Configure Factories for Complex Inheritance Source: https://jqno.nl/equalsverifier/manual/final-means-final Uses withRedefinedSubclass and withRedefinedSuperclass overloads to provide factories for complex inheritance patterns. ```java EqualsVerifier.forClass(Foo.class) .withFactory( values -> new Foo(values.getInt("i"), new Object()) values -> new Foo(values.getInt("i"), new Object()) {} ) .withRedefinedSubclass( values -> new SubFoo(values.getInt("i"), values.getString("s"), new Object()) ) .verify(); EqualsVerifier.forClass(SubFoo.class) .withFactory( values -> new SubFoo(values.getInt("i"), values.getString("s"), new Object()) values -> new SubFoo(values.getInt("i"), values.getString("s"), new Object()) {} ) .withRedefinedSuperclass( values -> new Foo(values.getInt("i"), new Object()) ) .verify(); ``` -------------------------------- ### Java Class Structure for equals() and hashCode() Source: https://jqno.nl/equalsverifier/manual/good-equals A basic Java class structure with fields, suitable for implementing equals() and hashCode() methods. ```java public class Person { private final String name; private final int age; public Point(String name, int age) { this.name = name; this.age = age; } // equals? // hashCode? } ``` -------------------------------- ### Java hashCode() Method using Objects.hash() Source: https://jqno.nl/equalsverifier/manual/good-equals A concise and recommended implementation for the hashCode() method, utilizing Objects.hash() to generate a hash code based on multiple fields. This should always be overridden when equals() is overridden. ```java public int hashCode() { return Objects.hash(name, age); } ``` -------------------------------- ### Provide Prefab Values for a Type Source: https://jqno.nl/equalsverifier/errormessages/add-prefab-values-for-one-of-the-following-types Use #withPrefabValues to supply pre-built instances of a type that EqualsVerifier cannot instantiate on its own. This is crucial when EqualsVerifier encounters recursive data structures or types with complex instantiation logic. ```java -> Recursive datastructure. Add prefab values for one of the following types: Foo. ``` -------------------------------- ### Define a generic class for testing Source: https://jqno.nl/equalsverifier/manual/prefab-values A sample class containing generic fields to be tested by EqualsVerifier. ```java class Foo { private final Bar stringBar; private final Bar intBar; // Constructor, equals(), hashCode() omitted } ``` -------------------------------- ### Test Specific Classes with EqualsVerifier Source: https://jqno.nl/equalsverifier/manual/several-classes-at-once Use `EqualsVerifier.forClasses()` to explicitly list and test multiple classes. This provides more control than package scanning and can be faster. ```java EqualsVerifier.forClasses(Student.class, Teacher.class, Staff.class, Address.class) .verify(); ``` -------------------------------- ### Add EqualsVerifier dependency (fat jar) for Maven Source: https://jqno.nl/equalsverifier Use this Maven dependency if you need a 'fat' jar of EqualsVerifier without transitive dependencies. ```xml nl.jqno.equalsverifier equalsverifier-nodep 4.4.2 test ``` -------------------------------- ### Verify Class with Mockito Mocking Source: https://jqno.nl/equalsverifier/manual/prefab-values Use this to verify a class when Mockito is available on the classpath. EqualsVerifier will attempt to use Mockito to mock fields, reducing the need for explicit prefab values. ```java EqualsVerifier.forClass(Book.class) .verify(); ``` -------------------------------- ### Optimization Comment for equals() Method Source: https://jqno.nl/equalsverifier/manual/good-equals A common optimization line for equals() methods, intended to quickly return true if the objects are the same instance. However, this is often counterproductive due to JVM optimizations. ```java if (this == obj) return true; ``` -------------------------------- ### Normalizing BigDecimal in constructor Source: https://jqno.nl/equalsverifier/errormessages/bigdecimal-equality Ensures all instances are normalized upon creation to allow standard equals and hashCode usage. ```java class Foo { ... Foo(BigDecimal bdField) { // Now if bdField is final it will only have instances // that are equal when compareTo is equal. // If mutable then setters will need to do the same. this.bdField = bdField.stripTrailingZeros(); } } ``` -------------------------------- ### Testing Abstract Superclass with EqualsVerifier Source: https://jqno.nl/equalsverifier/manual/jpa-entities Shows how to use EqualsVerifier to test an abstract superclass. The first test verifies the abstract class directly, while the second test verifies a concrete subclass, specifying only the 'id' field to be considered. ```java @Test public void testAbstractEntity() { EqualsVerifier.forClass(AbstractEntity.class) .verify(); } ``` ```java @Test public void testFoo() { EqualsVerifier.forClass(Foo.class) .withOnlyTheseFields("id") .verify(); } ``` -------------------------------- ### Implementing custom equality for BigDecimal Source: https://jqno.nl/equalsverifier/errormessages/bigdecimal-equality Logic for checking equality using compareTo instead of equals. ```java // true if bdField and other.bdField are // either both null or are equal using compareTo boolean comparablyEqual = (bdField == null && other.bdField == null) || (bdField != null && other.bdField != null && bdField.compareTo(other.bdField) == 0); ``` -------------------------------- ### Configure EqualsVerifier for Lombok cached hash codes Source: https://jqno.nl/equalsverifier/errormessages/significant-fields-equals-relies-on-foo-but-hashcode-does-not Use withLombokCachedHashCode to test classes utilizing Lombok's lazy hash code caching. ```java EqualsVerifier.forClass(LazyPojo.class) .withLombokCachedHashCode(new CachedHashCode("bar")); ``` -------------------------------- ### Configure EqualsVerifier for intermediate subclasses Source: https://jqno.nl/equalsverifier/manual/inheritance Combines 'withRedefinedSuperclass' and 'withRedefinedSubclass' to test a class that is both a subclass and a superclass. ```java EqualsVerifier.forClass(ColorPoint.class) .withRedefinedSuperclass() .withRedefinedSubclass(EnhancedColorPoint.class) .verify(); ``` -------------------------------- ### Provide Prefab Values for Recursive Data Structures Source: https://jqno.nl/equalsverifier/errormessages/recursive-datastructure Use `withPrefabValues` to supply predefined instances for classes involved in a recursive loop. This is necessary when EqualsVerifier cannot instantiate objects due to circular references in the object graph. Choose one of the classes in the loop to provide prefab values for. ```java EqualsVerifier.forClass(Foo.class) .withPrefabValues(Bar.class, new Bar(1), new Bar(2)) .verify(); ``` -------------------------------- ### Combine Suppressions and Prefab Values for Records Source: https://jqno.nl/equalsverifier/errormessages/record-failed-to-run-constructor Combine multiple suppressions and prefab value definitions to handle complex record constructor validation scenarios. ```java EqualsVerifier.forClass(Foo.class) .suppress(Warning.NULL_FIELDS, Warning.ZERO_FIELDS) .withPrefabValues(int.class, 42, 1337) .verify(); ``` -------------------------------- ### equals() Method for Older Java Versions Source: https://jqno.nl/equalsverifier/manual/good-equals Provides an implementation of the equals() method for Java versions prior to 17, using a traditional instanceof check and cast. It also uses Objects.equals() for null-safe comparison of non-primitive fields. ```java public boolean equals(Object obj) { if (!(obj instanceof Person)) { return false; } Person other = (Person) obj; return Objects.equals(name, other.name) && age == other.age; } ``` -------------------------------- ### ColorPoint equals Method Source: https://jqno.nl/equalsverifier/errormessages/coverage-is-not-100-percent This equals method for ColorPoint includes a canEqual check. The return statement after the canEqual call might not be covered if ColorPoint is a leaf node in the class hierarchy. ```java @Override public boolean equals(Object obj) { if (!(obj instanceof ColorPoint)) { return false; } ColorPoint other = (ColorPoint)obj; if (!other.canEqual(this)) { return false; } return super.equals(other) && color.equals(other.color); } ``` -------------------------------- ### Add EqualsVerifier dependency for Maven Source: https://jqno.nl/equalsverifier Include this Maven dependency in your project's pom.xml to use EqualsVerifier for testing. ```xml nl.jqno.equalsverifier equalsverifier 4.4.2 test ``` -------------------------------- ### Using Objects.equals for null-safe comparisons Source: https://jqno.nl/equalsverifier/errormessages/non-nullity-equals-hashcode-tostring-throws-nullpointerexception In Java 7 and later, use `Objects.equals` for null-safe comparisons in equals methods. This is a concise and recommended approach to avoid NullPointerExceptions. ```java return Objects.equals(foo, other.foo); ``` -------------------------------- ### Exclude Classes from Package Scan with EqualsVerifier Source: https://jqno.nl/equalsverifier/manual/several-classes-at-once When testing a package, exclude specific helper classes using `ScanOption.except()`. This prevents unnecessary verification of classes not intended for `equals` method testing. ```java EqualsVerifier.forPackage( "com.example.app.domain", ScanOption.except(Helper.class)) .verify(); ``` -------------------------------- ### Configure EqualsVerifier with generic prefab values Source: https://jqno.nl/equalsverifier/manual/prefab-values Use withGenericPrefabValues to provide a factory for generic types, avoiding the need for field-specific prefab values. ```java EqualsVerifier.forClass(Foo.class) .withGenericPrefabValues(Bar.class, t -> new Bar<>(t)); ```