AssertJ Ignore Fields Comparison Example
1. Introduction
AssertJ is a fluent assertion library for Java. It’s open-source and supported by the AssertJ team under Apache License 2.0. Its fluent API is designed to make assertions more readable and expressive. In this example, I will create a Java project that demonstrates Assertj ignore fields comparison class RecursiveAssertionAssert
‘s following ignoring
methods:
ignoringFields
– recursive assertion ignores the specified fields in the object.ignoringExpectedNullFields
– recursive assertion ignores the expected object’snull
fields.ignoringFieldsMatchingRegexes
– recursive assertion ignores the fields matching the specified regexes in the object.ignoringFieldsOfTypes
– recursive assertion ignores the object fields of the given types.
2. Setup
In this step, I will create a Java project AssertJ-Demo
with the AssertJ
library in Eclipse IDE. Figure 1 shows that assertj-core-3.25.3.jar
is included as a referenced library.
Download the AssertJ library from https://jar-download.com/artifacts/org.assertj/assertj-core if you don’t have it.
Right-click on the AssertJ-Demo
project, then select the Build Path->Add External Archives
to add it to the project.
3. User POJO
In this step, I will create a User.java
clas that has fields: age
, id
, name
, email
, cellPhone
, and homePhone
.
User.java
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | package org.zheng.demo; public class User { private int age; private String cellPhone; private String email; private String homePhone; private String id; private String name; public int getAge() { return age; } public String getCellPhone() { return cellPhone; } public String getEmail() { return email; } public String getHomePhone() { return homePhone; } public String getId() { return id; } public String getName() { return name; } public void setAge( int age) { this .age = age; } public void setCellPhone(String cellPhone) { this .cellPhone = cellPhone; } public void setEmail(String email) { this .email = email; } public void setHomePhone(String homePhone) { this .homePhone = homePhone; } public void setId(String id) { this .id = id; } public void setName(String name) { this .name = name; } @Override public String toString() { return "User [id=" + id + ", name=" + name + ", email=" + email + ", cellPhone=" + cellPhone + ", homePhone=" + homePhone + "]" ; } } |
4. Assertj Ignore Fields Comparison
In this step, I will create an AssertJApp.java
that compares two User
objects by ignoring some fields.
AssertJApp.java
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | package org.zheng.demo; import static org.assertj.core.api.Assertions.assertThat; public class AssertJApp { private static final String CELL_PHONE = "cellPhone" ; private static final String EMAIL = "email" ; private static final String NAME = "name" ; private static final String USER_ID = "id" ; public static void main(String[] args) { User actualUser = new User(); actualUser.setId(USER_ID); actualUser.setName(NAME); User expectedUser = new User(); expectedUser.setId(USER_ID); printoutUsers(actualUser, expectedUser); assertThat(actualUser).usingRecursiveComparison().ignoringFields(NAME, EMAIL).isEqualTo(expectedUser); assertThat(actualUser).usingRecursiveComparison().ignoringFields(EMAIL).isNotEqualTo(expectedUser); assertThat(actualUser).usingRecursiveComparison().ignoringExpectedNullFields().isEqualTo(expectedUser); expectedUser.setName(NAME); actualUser.setAge( 50 ); assertThat(actualUser).usingRecursiveComparison().ignoringFieldsOfTypes( int . class ).isEqualTo(expectedUser); actualUser.setCellPhone( "1234567" ); expectedUser.setCellPhone( "badPhone" ); actualUser.setAge( 0 ); printoutUsers(actualUser, expectedUser); assertThat(actualUser).usingRecursiveComparison().ignoringFieldsMatchingRegexes(CELL_PHONE) .isEqualTo(expectedUser); assertThat(actualUser).usingRecursiveComparison().ignoringActualNullFields().isNotEqualTo(expectedUser); expectedUser.setCellPhone( null ); printoutUsers(actualUser, expectedUser); assertThat(actualUser).usingRecursiveComparison().ignoringExpectedNullFields().isEqualTo(expectedUser); actualUser.setEmail(EMAIL); expectedUser.setEmail(EMAIL); printoutUsers(actualUser, expectedUser); assertThat(actualUser).usingRecursiveComparison().ignoringExpectedNullFields().isEqualTo(expectedUser); System.out.println( "AssertJApp completed fine." ); } private static void printoutUsers( final User actualUser, final User expectedUser) { System.out.println( "actualUser=" + actualUser.toString()); System.out.println( "expectedUser=" + expectedUser.toString()); } } |
- Line 21: the chained assertation
assertThat(actualUser).usingRecursiveComparison().ignoringFields(NAME, EMAIL).isEqualTo(expectedUser)
is readable. It’s almost like an English sentence: I assert that the actual user using recursive comparison by ignoring fields: NAME and EMAIL is equal to the expected user. - Line 22: similar to line 21, but only ignoring the
email
field. - Line 23, 40, 46: using
ignoringExpectedNullFields
to ignore the expected object’snull
fields - Line 27: using
ignoringFieldsOfTypes
to ignore theint
type. - Line 33: using
ignoringFieldsMatchingRegexes
to ignore thecellPhone
field. - Line 35: using
ignoringActualNullFields
to ignore the actual object’snull
fields.
5. Demo
5.1 Happy Path
In this step, I will run AssertJApp
as outlined in step 4. All assertions passed and you will see “AssertJApp completed fine” at the end of console
log.
AssertJApp Happy Path Output
1 2 3 4 5 6 7 8 9 | actualUser=User [id=id, name=name, email= null , cellPhone= null , homePhone= null ] expectedUser=User [id=id, name= null , email= null , cellPhone= null , homePhone= null ] actualUser=User [id=id, name=name, email= null , cellPhone= 1234567 , homePhone= null ] expectedUser=User [id=id, name=name, email= null , cellPhone=badPhone, homePhone= null ] actualUser=User [id=id, name=name, email= null , cellPhone= 1234567 , homePhone= null ] expectedUser=User [id=id, name=name, email= null , cellPhone= null , homePhone= null ] actualUser=User [id=id, name=name, email=email, cellPhone= 1234567 , homePhone= null ] expectedUser=User [id=id, name=name, email=email, cellPhone= null , homePhone= null ] AssertJApp completed fine. |
5.2 Error Path
In this step, I will comment the code in line 25 – expectedUser.setName(NAME)
in the AssertJApp
file so the actual user
and expected user
have a different value in the name
field. Execute it as a Java application. Instead of seeing “AssertJApp completed fine.” as step 5.1, you will see an error message that explains the failure reason.
AssertJApp Error Console
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | actualUser=User [id=id, name=name, email=null, cellPhone=null, homePhone=null] expectedUser=User [id=id, name=null, email=null, cellPhone=null, homePhone=null] Exception in thread "main" java.lang.AssertionError: Expecting actual: User [id=id, name=name, email=null, cellPhone=null, homePhone=null] to be equal to: User [id=id, name=null, email=null, cellPhone=null, homePhone=null] when recursively comparing field by field, but found the following difference: field/property 'name' differ: - actual value : "name" - expected value: null The recursive comparison was performed with this configuration: - the following types were ignored in the comparison: java.lang.Integer - no equals methods were used in the comparison EXCEPT for java JDK types since introspecting JDK types is forbidden in java 17+ (use withEqualsForType to register a specific way to compare a JDK type if you need it) - these types were compared with the following comparators: - java.lang.Double -> DoubleComparator[precision=1.0E-15] - java.lang.Float -> FloatComparator[precision=1.0E-6] - java.nio.file.Path -> lexicographic comparator (Path natural order) - actual and expected objects and their fields were compared field by field recursively even if they were not of the same type, this allows for example to compare a Person to a PersonDto (call strictTypeChecking(true) to change that behavior). - the introspection strategy used was: DefaultRecursiveComparisonIntrospectionStrategy at org.zheng.demo.AssertJApp.main(AssertJApp.java:27) |
- Line 4-8, 10-12: AssertJ error message is readable and explains the failure details.
6. Conclusion
In this example, I demonstrated Assertj ignore fields comparison class RecursiveAssertionAssert
with the following methods:
ignoringFields
– recursive assertion ignores the specified fields in the object.ignoringExpectedNullFields
– recursive assertion ignores the expected object’snull
fields.ignoringFieldsMatchingRegexes
– recursive assertion ignores the fields matching the specified regexes in the object.ignoringFieldsOfTypes
– recursive assertion ignores the object fields of the given types.
7. Download
This was an example of a java project that included AssertJ ignore fields comparison.
You can download the full source code of this example here: AssertJ Ignore Fields Comparison Example