Skip to content

Creating specific assertions

Mathieu CLAVEL edited this page Aug 28, 2013 · 22 revisions

(to main page)

Having custom assertions is great because they can be seen as a DSL with domain assertions, it will make your test assertions reflect the domain, it's a way to use Domain Driven Design Ubiquitous language in your tests.

Creating its own assertions is simple : create a class inheriting from AbstractAssert and add your custom assertions method.
To be easy to use, you should also add a static method assertThat to provide an handy entry point to your new assertion class.

If you have a lot of classes you want to have assertions for, consider generating assertions.

Creating your own assertion class

Let's see how to do that on an example !

The example is taken from assertj-examples and more specifically in TolkienCharacterAssert.java.

The class we want to make assertion on is TolkienCharacter :

// getter/setter not shown for brevity
public class TolkienCharacter {
  private String name;
  private Race race;
  private int age;
}

We define TolkienCharacterAssert by inheriting from AbstractAssert and specifying the generic parameters, first is the class itself (needed for assertion chaining) and second is the class we want to make assert on : TolkienCharacter.

Inherits from AbstractAssert will provide you all the basic assertions (isEqualTo, isNull, ...).

// javadoc omitted for brevity
// 1 - inherits from AbstractAssert !
public class TolkienCharacterAssert extends AbstractAssert<TolkienCharacterAssert, TolkienCharacter> {

  // 2 - Write a constructor to build your assertion class from the object you want make assertions on.
  public TolkienCharacterAssert(TolkienCharacter actual) {
    super(actual, TolkienCharacterAssert.class);
  }

  // 3 - A fluent entry point to your specific assertion class, use it with static import.
  public static TolkienCharacterAssert assertThat(TolkienCharacter actual) {
    return new TolkienCharacterAssert(actual);
  }

  // 4 - a specific assertion !
  public TolkienCharacterAssert hasName(String name) {
    // check that actual TolkienCharacter we want to make assertions on is not null.
    isNotNull();

    // check condition
    if (!actual.getName().equals(name)) {
      failWithMessage("Expected character's name to be <%s> but was <%s>", name, actual.getName());
    }

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

  // 4 - another specific assertion !
  public TolkienCharacterAssert hasAge(int age) {
    // check that actual TolkienCharacter we want to make assertions on is not null.
    isNotNull();

    // check condition
    if (actual.getAge() != age) {
      failWithMessage("Expected character's age to be <%s> but was <%s>", age, actual.getAge());
    }

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

Providing a single entry point for all assertions : yours + AssertJ ones

It's easy :

  1. Create a class inheriting from org.assertj.core.api.Assertions.
  2. Add assertThat static method providing entry point to your own assertion :

Example taken from MyProjectAssertions.java in assertj-examples :

// extending make all standard AssertJ assertions available.
public class MyProjectAssertions extends Assertions { 

  // add the custom assertions related to MyProject  
  public static TolkienCharacterAssert assertThat(TolkienCharacter actual) {
    return new TolkienCharacterAssert(actual);
  }
}

Generating specific assertions with assertj assertions generator

If you have a lot of classes and want custom assertions for all of them, it can be a lot of work !
In that case, you can generate custom assertions with an assertions generator that takes classes or packages as input and generate the corresponding specific assertion classes (for all classes of specified packages and subpackages).

The assertions generator looks for properties to know what to generate. For example, if you have a Person class with an address property, it will generate hasAddress assertion as part of PersonAssert assertion class.

The best way to generate assertions is to use the maven assertions generator plugin.

Once assertions classes are generated, you can move them in source control and complete them with new assertions.

Soon, we will provide an eclipse assertions generator plugin, which is able generate assertions for a specific class (one at a time).

Something went wrong with that request. Please try again.