In this post we’re going to figure out how AssertJ can make our life easier if we need to validate complex objects in Java.
Let’s start with the simple object Author
that has only 2 fields
public class Author {
private String firstName ;
private String lastName ;
public Author ( String firstName , String lastName ) {
this . firstName = firstName ;
this . lastName = lastName ;
}
...
public String toString () {
Gson gson = new GsonBuilder (). setPrettyPrinting (). create ();
return gson . toJson ( this );
}
}
AssertJ maven dependency
<dependency>
<groupId> org.assertj</groupId>
<artifactId> assertj-core</artifactId>
<!-- use 2.9.0 for Java 7 projects -->
<version> 3.9.0</version>
<scope> test</scope>
</dependency>
Regular objects validation in Java with AssertJ
SoftAssertions assertions = new SoftAssertions ();
Author expectedAuthor = new Author ( "John" , "Doe" );
Author actualAuthor = new Author ( "John" , "Doe" );
assertions . assertThat ( actualAuthor . getFirstName ()). as ( "firstName" )
. isEqualTo ( expectedAuthor . getFirstName ());
assertions . assertThat ( actualAuthor . getLastName ()). as ( "lastName" )
. isEqualTo ( expectedAuthor . getLastName ());
assertions . assertAll ();
see AssertJ. Custom fail messages (assertion messages)
Validate objects with isEqualToComparingFieldByField. AssertJ
SoftAssertions assertions = new SoftAssertions ();
Author expectedAuthor = new Author ( "John" , "Doe" );
Author actualAuthor = new Author ( "John" , "Doe" );
assertions . assertThat ( actualAuthor ). as ( "Author" )
. isEqualToComparingFieldByField ( expectedAuthor );
assertions . assertAll ();
Even for simple objects like this we already have some benefits - less code.
Let’s see how failures look like if something is wrong with our object, for example actualAuthor = new Author("Jane", "Doe");
.
The following assertion failed:
1) [Author]
Expecting value <"John"> in field <"firstName"> but was <"Jane"> in <{
"firstName": "Jane",
"lastName": "Doe"
}>.
Comparison was performed on all fields
Very informative and readable, isn’t it?
Validate objects with isEqualToComparingFieldByFieldRecursively. AssertJ
In the real world we have to validate objects much more complex then the example above.
Let’s make it more complex
public class Book {
private String title ;
private Author author ;
private int year ;
private int pages ;
public Book ( String title , Author author , int year , int pages ) {
this . title = title ;
this . author = author ;
this . year = year ;
this . pages = pages ;
}
...
public String toString () {
Gson gson = new GsonBuilder (). setPrettyPrinting (). create ();
return gson . toJson ( this );
}
}
Our test looks like this
SoftAssertions assertions = new SoftAssertions ();
Book expectedBook = new Book ( "Book title" , new Author ( "John" , "Doe" ), 2018 , 300 );
Book actualBook = new Book ( "Book title" , new Author ( "John" , "Doe" ), 2018 , 300 );
assertions . assertThat ( expectedBook ). as ( "Book" )
. isEqualToComparingFieldByFieldRecursively ( actualBook );
assertions . assertAll ();
Let’s see how the failure would look like if something is wrong with actualBook, for example actualBook = new Book("Book title", new Author("Jane", "Doe"), 2018, 300);
The following assertion failed:
1) [Book]
Expecting:
<{
"title": "Book title",
"author": {
"firstName": "John",
"lastName": "Doe"
},
"year": 2018,
"pages": 300
}>
to be equal to:
<{
"title": "Book title",
"author": {
"firstName": "Jane",
"lastName": "Doe"
},
"year": 2018,
"pages": 300
}>
when recursively comparing field by field, but found the following difference(s):
Path to difference: <author.firstName>
- expected: <"Jane">
- actual : <"John">
You have everything to quckly understand why it’s failing and what is wrong with the object that you validate.
Validate objects with isEqualToIgnoringGivenFields. AssertJ
What if we accept any author’s firstName but expect the exact lastName (in our case “Doe”)? In that case the test would look like this
SoftAssertions assertions = new SoftAssertions ();
Book expectedBook = new Book ( "Book title" , new Author ( "John" , "Doe" ), 2018 , 300 );
Book actualBook = new Book ( "Book title" , new Author ( "Jane" , "Doe" ), 2018 , 300 );
assertions . assertThat ( expectedBook ). as ( "Book" )
. isEqualToIgnoringGivenFields ( actualBook , "author" );
assertions . assertThat ( expectedBook . getAuthor ()). as ( "Book.Author" )
. isEqualToIgnoringGivenFields ( actualBook . getAuthor (), "firstName" );
assertions . assertAll ();
Validate objects with isEqualToComparingOnlyGivenFields. AssertJ
There is another way to that with isEqualToComparingOnlyGivenFields
.
SoftAssertions assertions = new SoftAssertions ();
Book expectedBook = new Book ( "Book title" , new Author ( "John" , "Doe" ), 2018 , 300 );
Book actualBook = new Book ( "Book title" , new Author ( "Jane" , "Doe" ), 2018 , 300 );
assertions . assertThat ( expectedBook ). as ( "Book" )
. isEqualToComparingOnlyGivenFields ( actualBook , "title" , "year" , "pages" );
assertions . assertThat ( expectedBook . getAuthor ()). as ( "Book.Author" )
. isEqualToComparingOnlyGivenFields ( actualBook . getAuthor (), "lastName" );
assertions . assertAll ();
Try it - you’ll love it.
You may also find these posts interesting: