Home Tutorials Training Consulting Products Books Company Donate Contact us









NOW Hiring

Quick links

Share

AssertJ tutorial. This tutorial describes the usage of the AssertJ framework for writing compact tests.

1. Introduction to AssertJ

The AssertJ project provides fluent assertion statements for Java. These assert statements are typically used with Java JUnit tests. AssertJ is a fork of the Fest assert library, as Fest is not actively maintained anymore.

AssertJ is a library for simplifying the writing of assert statements in tests. It also improves the readability of asserts statements. It has a fluent interface for assertions, which makes it easy for your code completion to help your write them. The base method for AssertJ assertions is the assertThat method followed by the assertion.

2. Benefits of using AssertJ

Using AssertJ improves the readability of your tests. While you may be familiar with JUnits assertions it is easy for a beginner to mix up actual and expected.

assertEquals(actual, expected);
assertThat(actual).isEqualTo(expected);
// this look obviously wrong
assertThat(expected).isEqualTo(actual);

It makes it easier to express your intent.

Date today = new Date();
assertTrue((birthday.getTime() > today.getTime()));
assertThat(birthday).isBefore(today);

AssertJ also provides you with readable errors messages for test errors.

List<String> list = new ArrayList<>();
assertTrue(list.contains("abc"));
->
java.lang.AssertionError at ...

assertThat(list).contains("abc");
->
java.lang.AssertionError:
    Expecting:
         <[]>
        to contain:
         <["abc"]>
        but could not find:
         <["abc"]>

3. Using AssertJ

3.1. Gradle

To use AssertJ in your Gradle build for unit tests add the following dependency to your Gradle build file.

// use 2.6.0 for Java 7 projects
testCompile 'org.assertj:assertj-core:3.6.2'

3.2. Maven

To use the library for a Maven based project, the following dependency to your pom file.

<dependency>
  <groupId>org.assertj</groupId>
  <artifactId>assertj-core</artifactId>
  <!-- use 2.6.0 for Java 7 projects -->
  <version>3.6.2</version>
  <scope>test</scope>
</dependency>

3.3. Eclipse IDE configuration

To simplify the usage of the AssertJ assertThat statement in the Eclipse IDE go to Window ▸ Preferences ▸ Java ▸ Editor ▸ Content assist ▸ Favorites ▸ New Type, enter org.assertj.core.api.Assertions and confirm.

You should see org.assertj.core.api.Assertions.* in the list.

3.4. IntelliJ Idea configuration

No special is needed configuration, just start typing assertThat and then invoke completion (Ctrl-Space) twice.

4. Usage of AssertJ

4.1. Writing assertions

AssertJ assertions start with a call to assertThat followed by an assertion.

assertThat("abc").isEqualTo(123);

4.2. Chaining of assertions

AssertJ allows you to be concise by chaining multiple assertions.

// JUnit style
assertNotNull(list);
assertTrue(list.isEmpty());

// AssertJ
assertThat(list).isNotNull().isNotEmpty();

4.3. Assertions for Java collections

AssertJ comes with many built in matchers for Java collection classes.

For example the List class:

assertThat(userList).contains(user, atIndex(0)).containsOnlyOnce(user, user2, user3);
assertThat(userList).contains(user).isSortedAccordingTo(ageComparator);

Here is an example that tests a Map:

// check for multiple keys at once
assertThat(map).containsKeys("a", "b", "c");
// check if the value of a certain key satisfies a condition
assertThat(map).hasEntrySatisfying(key, String::isEmpty);
// check if all entries of an other map are contained in a map
assertThat(map).containsAllEntriesOf(expectedSubset);

4.4. Assertions for Date

AssertJ provides special assertions for the Java date class.

assertThat(eclipseOxygen.getReleaseDate()).isBeforeYear(2020).isAfterYear(2016);
assertThat(eclipseOxygen.getReleaseDate()).isBetween("2017-01-31", "2017-12-31");

4.5. Assertions for File and Stream

There are assertions to handle common file and stream checks.

// file assertions:
assertThat(manifestFile).exists();
assertThat(contentOf(manifestFile)).startsWith("Manifest-Version:");

// stream assertions:
assertThat(streamFromFile).hasSameContentAs(streamFrom(streamFromFileCopy));

4.6. Adding a custom message to an assertion

We can add a customized message to existing assertions to better explain what we are expecting. For this purpose we use the as() method in our assertion chain:

User user = new User("admin");
assertThat(user.getPostCount()).as("User \"%s\" has no posts", user.getName()).isEqualTo(0);

4.7. Comparing objects field by field

Sometimes you don’t want to use the existing equals() method but just want to compare by certain fields. AssertJ provides multiple assertions to help you with that:

assertThat(user).isEqualToComparingOnlyGivenFields(otherUser, "address", "age");

If you have to problem the classes of certain fields don’t implement equals you can use isEqualToComparingFieldByFieldRecursively.

assertThat(user).isEqualToComparingFieldByFieldRecursively(otherUser);

4.8. Further examples

The following example code is taken from the AssertJ homepage:

// unique entry point to get access to all assertThat methods and utility methods (e.g. entry)
import static org.assertj.core.api.Assertions.*;

// common assertions
assertThat(frodo.getName()).isEqualTo("Frodo");
assertThat(frodo).isNotEqualTo(sauron)
                 .isIn(fellowshipOfTheRing);

// String specific assertions
assertThat(frodo.getName()).startsWith("Fro")
                           .endsWith("do")
                           .isEqualToIgnoringCase("frodo");

// collection specific assertions
assertThat(fellowshipOfTheRing).hasSize(9)
                               .contains(frodo, sam)
                               .doesNotContain(sauron);

// using extracting magical feature to check fellowshipOfTheRing characters name :)
assertThat(fellowshipOfTheRing)
    .extracting("name")
    .contains("Boromir", "Gandalf", "Frodo", "Legolas")
    .doesNotContain("Sauron", "Elrond");

// map specific assertions, ringBearers initialized with the elves rings and the one ring bearers.
assertThat(ringBearers).hasSize(4)
                       .contains(entry(oneRing, frodo), entry(nenya, galadriel))
                       .doesNotContainEntry(oneRing, aragorn);

// and many more assertions : dates, file, numbers, exceptions ...

5. Converting JUnit assertions to AssrtJ with a script

The AssertJ project provides scripts for all major operating systems to automatically convert tests with JUnit assertions to AssertJ.

You can download them from their Github repository: Script for Unix/Windows Script for OSX

Just copy the script into the folder of the tests you want to convert and execute it.

# Unix/Windows
convert-junit-assertions-to-assertj.sh
# OSX
convert-junit-assertions-to-assertj-on-osx.sh
 1 - Replacing : assertEquals(0, myList.size()) ................. by : assertThat(myList).isEmpty()
 2 - Replacing : assertEquals(expectedSize, myList.size()) ...... by : assertThat(myList).hasSize(expectedSize)

While this script works pretty well it can still introduce compile errors that you have to fix manually. For more information on this topic please see the AssertJ project website.

6. Exercise: Creating a custom assertion for a class

While it is nice to have the ability to define custom error messages in the test, if we want to use this in multiple tests this can be come tedious and leads to redundant code. In this case it is useful to created custom assertion classes that are reusable. For this exercise we want to take our custom message example:

@Test
public void newlyCreatedUserHasNoPosts() throws Exception {
    User user = new User("admin");
    assertThat(user.getPostCount()).as("User \"%s\" has no posts", user.getName()).isEqualTo(0);
}

And transform it into this:

@Test
public void newlyCreatedUserHasNoPosts() throws Exception {
    User user = new User("admin");
    assertThat(user).hasNoPosts();
}

6.1. Implementation

First we have to define our entry point class that lets us start the assertion chain. We have to provide a static assertThat method that returns our assertion class.

public class Assertions {

  public static UserAssert assertThat(User actual) {
    return new UserAssert(actual);
  }
}

Now we create the missing assertion class.

public class UserAssert extends AbstractAssert<UserAssert, User> {

    public UserAssert hasNoPosts() {
          // check that actual User we want to make assertions on is not null.
          isNotNull();

          // overrides the default error message with a more explicit one
          String assertjErrorMessage = "\nExpecting User <%s> to have no posts\n but was:\n  <%s> posts";

          // null safe check
          int actualNumberOfPosts = actual.getPostCount();
          if (!Objects.areEqual(actualNumberOfPosts, 0)) {
            failWithMessage(assertjErrorMessage, actual.getName(), actualNumberOfPosts);
          }

          // return the current assertion for method chaining
          return this;
        }

    public UserAssert(User actual) {
        super(actual, UserAssert.class);
    }

    public static UserAssert assertThat(User actual) {
        return new UserAssert(actual);
    }

}

6.2. Validating

Now we can execute our test:

@Test
public void newlyCreatedUserHasNoPosts() throws Exception {
    User user = new User("admin");
    UserAssert.assertThat(user).hasNoPosts();
}

java.lang.AssertionError:
Expecting User <admin> to have no posts
 but was:
  <42> posts

The AssertJ project provides generators that let you generate custom assertions from your existing Java classes in an automated way. You can learn more about this feature on their website.

7. Using AssertJ Android

AssertJ Android allows you to write efficient assertions for Android. The following examples are taken from their Github page for AssertJ Android.

// check visibility of view with JUnit
assertEquals(View.GONE, view.getVisibility());

// AssertJ Androids version is much shorter
assertThat(view).isGone();

// AssertJ Android allows to combine checks
assertThat(layout).isVisible()
    .isVertical()
    .hasChildCount(4)
    .hasShowDividers(SHOW_DIVIDERS_MIDDLE);

8. About this website

9. AssertJ resources

9.1. vogella GmbH training and consulting support

TRAINING SERVICE & SUPPORT

The vogella company provides comprehensive training and education services from experts in the areas of Eclipse RCP, Android, Git, Java, Gradle and Spring. We offer both public and inhouse training. Whichever course you decide to take, you are guaranteed to experience what many before you refer to as “The best IT class I have ever attended”.

The vogella company offers expert consulting services, development support and coaching. Our customers range from Fortune 100 corporations to individual developers.

Copyright © 2012-2017 vogella GmbH. Free use of the software examples is granted under the terms of the EPL License. This tutorial is published under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Germany license.

See Licence.