Using AssertJ for assertions

In this recipe, we will add AssertJ to your classpath (or check if it's already there) and take a look at a test that should show the concept that lies behind the AssertJ library.

Getting ready

First, let's check the differences between the different AssertJ JAR files:

  • assertj-core: This file contains the vast majority of assertions (there is rarely a need to have any additional dependencies)
  • assertj-guava: This file contains additional assertions for some of the Guava library related classes
  • assertj-neo4j: This file contains additional assertions for the Neo4j graph database related classes
  • assertj-joda-time: This file contains additional assertions for the JodaTime library related classes
  • assertj-assertions-generator-maven-plugin: This is a Maven plugin for generating AssertJ assertions

In most cases, all you need is assertj-core since it already has plenty of useful assertions.

Regardless of the fact that you are using JUnit or TestNG, you still have to add assertj-core to your classpath since it isn't embedded into either of them.

The following is the dependency for AssertJ core (Maven):

<dependency>
    <groupId>org.assertj</groupId>
    <artifactId>assertj-core</artifactId>
    <version>1.6.0</version>
    <scope>test</scope>
</dependency>

The following is the dependency for AssertJ core (Gradle):

testCompile('org.assertj:assertj-core:1.6.0')

If you are not using any of the dependency managers, you have to download one of the aforementioned JAR files and add them to your classpath.

For this recipe, our system under test will be a NewPersonGenerator class that will call an external service, NewIdentityCreator, to generate a new identity for the current person, as shown in the following code:

public class NewPersonGenerator {

    private final NewIdentityCreator newIdentityCreator;

    public NewPersonGenerator(NewIdentityCreator newIdentityCreator) {
        this.newIdentityCreator = newIdentityCreator;
    }

    public Person generateNewIdentity(Person person) {
        String newName = newIdentityCreator.createNewName(person);
        int newAge = newIdentityCreator.createNewAge(person);
        List<Person> newSiblings = newIdentityCreator.createNewSiblings(person);
        return new Person(newName, newAge, newSiblings);
    }
}

How to do it...

In order to use the AssertJ assertions in your tests, you have to perform the following steps:

  1. Add the AssertJ dependencies to your classpath.
  2. Call Assertions.assertThat(T object).someAssertionMethod(...) to perform assertion.

The following snippet depicts the aforementioned scenario for JUnit (refer to Chapter 1, Getting Started with Mockito for information on the TestNG configuration):

@RunWith(MockitoJUnitRunner.class)
public class NewPersonGeneratorTest {

    @Mock NewIdentityCreator newIdentityCreator;

    @InjectMocks NewPersonGenerator systemUnderTest;

    @Test
    public void should_return_person_with_new_identity() {
        // given
        Person person = new Person("Robert", 25, asList(new Person("John", 10), new Person("Maria", 12)));
        given(newIdentityCreator.createNewName(person)).willReturn("Andrew");
        given(newIdentityCreator.createNewAge(person)).willReturn(45);
        given(newIdentityCreator.createNewSiblings(person)).willReturn(asList(new Person("Amy", 20), new Person("Alex", 25)));

        // when
        Person newPerson = systemUnderTest.generateNewIdentity(person);

        // then
        assertThat(newPerson).isNotNull().isNotEqualTo(person);
        assertThat(newPerson.getName()).isNotNull().startsWith("And").endsWith("rew");
        assertThat(newPerson.getSiblings()).contains(new Person("Amy", 20), new Person("Alex", 25));
        assertThat(newPerson.getAge()).isGreaterThan(25);
        assertThat(newPerson.getSiblings()).extracting("name", "age").contains(tuple("Amy", 20), tuple("Alex", 25));
    }

}

How it works...

When you call Assertions.assertThat(T object), you can benefit from AssertJ's overloaded assertThat(…) methods that can be used with different types of classes. The examples of such classes are given as follows:

  • public static BigDecimalAssert assertThat(BigDecimal actual);
  • public static BooleanAssert assertThat(boolean actual);
  • public static FileAssert assertThat(File actual);
  • public static <T> ObjectAssert<T> assertThat(T actual);

Each of the overloaded assertThat(…) methods delegates to the instantiation of the proper implementation of the AbstractAssert class that contains all of the basic assertions that come from implementing the Assert interface. You also have access to the actual field called actual that contains the object you are performing assertion against (which allows you to create your custom assertions quickly).

Due to the fact that AssertJ operates on overloaded methods that are always type-specific, your IDE will instantly help you find all of the matching assertion methods. For example, in the previous code snippet, we presented assertions for Files as assertThat(File actual). The execution of this method will return FileAssert that is file-specific and allows you to use such methods as follows (to mention only a few):

exists(), isDirectory(), isRelative(), hasParent(...),hasExtension(...)

Since AssertJ's main concept is to operate on fluent interfaces, and each assertion returns the assertion implementation itself, you do not have to combine several assertions into a single one as done in Hamcrest. Instead, you can just execute a chain of methods as follows:

assertThat(newPerson).isNotNull().isNotEqualTo(person);

AssertJ also proves to be extremely powerful in terms of performing assertions over iterables as follows:

assertThat(newPerson.getSiblings()).extracting("name", "age").contains(tuple("Amy", 20), tuple("Alex", 25));

You can easily extract (using the extracting method) certain properties of each of the iterables and check their state in comparison to specially created objects called tuples (check AssertJ examples of asserting iterables at https://github.com/joel-costigliola/assertj-examples/blob/master/assertions-examples/src/test/java/org/assertj/examples/IterableAssertionsExamples.java).

Tuples allow you to create a structure matching your extracted elements. In other words, for the aforementioned siblings that are of a Person type, we extract two strings from the properties name and age Next, we compare them against a structure having name equal to Amy and age equal to 20 and then against name equal to Alex and age equal to 25. Of course, this is only a small portion of AssertJ possibilities, but it should give you a clue of how powerful and readable AssertJ is.

There's more...

From AssertJ version 1.6.0, you can make your tests look even more readable and follow the BDD naming by changing the assertThat(...) method into the then(...) method. You can rewrite the test to follow that approach, as shown in the following code:

    @Test
    public void should_return_person_with_new_identity() {
        // given
        Person person = new Person("Robert", ROBERT_AGE,newArrayList(new Person("John", 10), new Person("Maria", 12)));
        given(newIdentityCreator.createNewName(person)).willReturn("Andrew");
        given(newIdentityCreator.createNewAge(person)).willReturn(45);
        given(newIdentityCreator.createNewSiblings(person)).willReturn(newArrayList(new Person("Amy", 20),new Person("Alex", 25)));

        // when
        Person newPerson = systemUnderTest.generateNewIdentity(person);

        // then
        then(newPerson).isNotNull().isNotEqualTo(person);
        then(newPerson.getName()).isNotNull().startsWith("And").endsWith("rew");
        then(newPerson.getSiblings()).contains(new Person("Amy", 20), new Person("Alex", 25));
        then(newPerson.getAge()).isGreaterThan(25);
        then(newPerson.getSiblings()).extracting("name", "age").contains(tuple("Amy", 20), tuple("Alex", 25));
    }

See also

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.12.166.131