Moving on to Assertj assertions – beginner examples

Assertj examples

This post describes the use of a relatively new but a fluent assertion library, Assertj.

1. Introduction

Assertj provides simple yet effective way to assert your tests. It provides a powerful mechanism to make your assertions compact and readable.

2. Dependencies

Add the following dependency to your project.

Gradle:

[code language=”plain”]
testCompile ‘org.assertj:assertj-core:3.5.2’
[/code]

Maven:

[code language=”xml”]
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>3.5.2</version>
</dependency>
[/code]

3. Getting ready for the examples

We will deal with some real examples in this tutorial. Hence, we need a project setup to work with. Please note that all the source code used in this tutorial can be found on github. Link is at the end of the post.

Our data model class HogwartsAllumni.java

[code language=”java”]
package org.websandbox.learning.assertj.model;

public class HogwartsAllumni {

private String name;
private House house;

public HogwartsAllumni(String name) {
this.name = name;
}

public HogwartsAllumni(String name, House house) {
this.name = name;
this.house = house;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public House getHouse() {
return house;
}

public void setHouse(House house) {
this.house = house;
}
}
[/code]

The enum House.java

[code language=”java”]
package org.websandbox.learning.assertj.model;
public enum House {

GRYFFINDOR, HELGA_HUFFLEPUFF, ROWENA_RAVENCLAW, SALAZAR_SLYTHERIN;
}
[/code]

Pretty self explanatory.

Our repository, that will provide us the required data. This is the class that we are planning to test. DaoRepository.java

[code language=”java”]
package org.websandbox.learning.assertj.persistence;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.websandbox.learning.assertj.model.HogwartsAllumni;
import org.websandbox.learning.assertj.model.House;

public class DaoRepository {

private HogwartsAllumni harry = new HogwartsAllumni("Harry", House.GRYFFINDOR);
private HogwartsAllumni ron = new HogwartsAllumni("Ron", House.GRYFFINDOR);
private HogwartsAllumni snape = new HogwartsAllumni("Snape", House.SALAZAR_SLYTHERIN);

public HogwartsAllumni findByName(String name) {
return new HogwartsAllumni(name);
}

public List<HogwartsAllumni> findAllByHouse(House house) {
switch (house) {
case GRYFFINDOR:
return Arrays.asList(harry, ron);
case SALAZAR_SLYTHERIN:
return Arrays.asList(snape);
default:
return new ArrayList<>();
}
}

public List<HogwartsAllumni> findAll() {
List<HogwartsAllumni> allumni = new ArrayList<>(3);
allumni.add(harry);
allumni.add(ron);
allumni.add(snape);
return allumni;
}
}
[/code]

This class basically mimics the dao layer. That’s it. We will now move ahead with the actual examples.

4. Examples

It all starts with “assertThat”.

The assertj assertions start with the call to assertThat(). For example,

[code language=”java”]
assertThat(objectReturnedFrmRepo).isEqualTo(expectedObject);
[/code]

Note: Please make sure that you use the

[code language=”java”]
import static org.assertj.core.api.Assertions.assertThat;
[/code]

and not

[code language=”java”]
import static org.junit.Assert.assertThat;
[/code]

Initial setup for the test class. DaoRepositoryTest.java

[code language=”java”]
package org.websandbox.learning.assertj.persistence;

import static org.assertj.core.api.Assertions.assertThat;

import java.util.List;
import java.util.stream.Collectors;

import org.junit.Test;
import org.websandbox.learning.assertj.model.HogwartsAllumni;
import org.websandbox.learning.assertj.model.House;

public class DaoRepositoryTest {

private DaoRepository repository = new DaoRepository();
private HogwartsAllumni harry = new HogwartsAllumni("Harry", House.GRYFFINDOR);
private HogwartsAllumni ron = new HogwartsAllumni("Ron", House.GRYFFINDOR);
private HogwartsAllumni snape = new HogwartsAllumni("Snape", House.SALAZAR_SLYTHERIN);
private HogwartsAllumni hegla = new HogwartsAllumni("Hegla", House.HELGA_HUFFLEPUFF);

@Test
public void myTest() {
//nothing here
}
}
[/code]

Ok, so the basic structure of our class is ready. Let’s go ahead and write our first test.

[code language=”java”]
@Test
public void findHarry() {
HogwartsAllumni harry = repository.findByName("Harry");
assertThat(harry.getName()).isEqualTo("Harry");
}
[/code]

This is pretty straightforward. We are expecting to get the HogwartsAllumni with name “Harry” from the repository.


[code language=”java”]
@Test
public void findAllOfThemAndCheckWhoIsPresent() {
List<HogwartsAllumni> allOfThem = repository.findAll();
assertThat(allOfThem).hasSize(3).extracting(HogwartsAllumni::getName).contains(harry.getName(),
ron.getName(), snape.getName());
}
[/code]

We are fetching all the HogwartsAllumnis present in our repository. We make sure that there are only 3 instances present using hasSize(3).

The extracting(HogwartsAllumni::getName) might look a bit weird to you if you are not familiar with java 8. Essentially, we are calling the getName() method on all the instances present in ‘allOfThem’ list. Then, we check that the result contains at least the three names passed in contains() method. Even if we pass any two names (or a single name for that matter) like contains(harry.getName(), snape.getName()) or contains(snape.getName()), the test will pass.


[code language=”java”]
@Test
public void findAllOfThemAndCheckWhoIsNotPresent() {
List<HogwartsAllumni> allOfThem = repository.findAll();
assertThat(allOfThem).extracting(HogwartsAllumni::getName).doesNotContain(hegla.getName());
}
[/code]

Here, we have used the counterpart of contains() i.e. doesNotContain(). We are making sure that we do not have helga in our result.


We can combine the contains() and doesNotContain() in a single chain like

[code language=”java”]
assertThat(allOfThem).extracting(HogwartsAllumni::getName).contains(harry.getName(), ron.getName(),
snape.getName()).doesNotContain(hegla.getName());
[/code]


We can provide the description of what we are testing. This will appear when the test case fails.

[code language=”java”]
@Test
public void failingAssertionWithCustomMessage() {
// It is in the destiny of this test case to fail so that the muggles
// can see the descriptive message
assertThat(harry.getHouse()).as("Check %s’s house", harry.getName()).isEqualTo(House.SALAZAR_SLYTHERIN);
}
[/code]

The error message for the above test case will be

[code language=”plain”]
org.junit.ComparisonFailure: [Check Harry’s house] expected:<[SALAZAR_SLYTHERIN]> but was:<[GRYFFINDOR]>
[/code]


We can also apply filters if we are interested in only a subset of the results.

[code language=”java”]
@Test
public void filterByHouse() {
List<HogwartsAllumni> gryffindors = repository.findAllByHouse(House.GRYFFINDOR);
assertThat(gryffindors).filteredOn(character ->
character.getHouse().equals(House.GRYFFINDOR)).containsOnly(harry, ron);
}
[/code]

Here, we are considering the characters whose house is “GRYFFINDOR”. Also, note that we have used containsOnly() here. Meaning, removing harry or ron from the arguments list will result in a failure. This is because the containsOnly method is strict. The lists to be compared must be exactly similar.

Wait a second, we have passed the object references directly as opposed to the harry.getname() previously. This will result in a failure because all the methods of the ‘contains’ family simply uses the object’s equals() method to compare. There are two solutions t overcome this.

First, add equals() (and also hashCode()) method to HogwartsAllumni. you can use eclipse generated implementations.

[code language=”java”]
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((house == null) ? 0 : house.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}

@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
HogwartsAllumni other = (HogwartsAllumni) obj;
if (house != other.house)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
[/code]

The second option is to compare the objects by their first name.

[code language=”java”]
@Test
public void filterByHouseAndCompareUsingName() {
List<HogwartsAllumni> gryffindors = repository.findAllByHouse(House.GRYFFINDOR);
assertThat(gryffindors).filteredOn(character -> character.getHouse().equals(House.GRYFFINDOR))
.extracting(HogwartsAllumni::getName).containsOnly(harry.getName(), ron.getName());
}
[/code]

Note the use of extracting() in the above example. If you do this, no need to implement the equals() method.


5. Resources

  1. Assertj GitHub project
  2. Source code for this post