Introduction à AssertJ

Cet article fait partie d'une série: • Introduction à AssertJ (article actuel) • AssertJ pour Guava

• Fonctionnalités Java 8 d'AssertJ

• Assertions personnalisées avec AssertJ

1. Aperçu

Dans cet article, nous explorerons AssertJ - une bibliothèque open source basée sur la communauté utilisée pour écrire des assertions fluides et riches dans les tests Java.

Cet article se concentre sur les outils disponibles dans le module de base AssertJ appelé AssertJ-core .

2. Dépendances de Maven

Pour utiliser AssertJ, vous devez inclure la section suivante dans votre fichier pom.xml :

 org.assertj assertj-core 3.4.1 test  

Cette dépendance ne couvre que les assertions Java de base. Si vous souhaitez utiliser des assertions avancées, vous devrez ajouter des modules supplémentaires séparément.

Notez que pour Java 7 et versions antérieures, vous devez utiliser AssertJ core version 2.xx

Les dernières versions peuvent être trouvées ici.

3. Présentation

AssertJ fournit un ensemble de classes et de méthodes utilitaires qui nous permettent d'écrire facilement des assertions fluides et belles pour:

  • Java standard
  • Java 8
  • Goyave
  • Heure Joda
  • Neo4J et
  • Composants de balançoire

Une liste détaillée de tous les modules est disponible sur le site Web du projet.

Commençons par quelques exemples, issus directement de la documentation d'AssertJ:

assertThat(frodo) .isNotEqualTo(sauron) .isIn(fellowshipOfTheRing); assertThat(frodo.getName()) .startsWith("Fro") .endsWith("do") .isEqualToIgnoringCase("frodo"); assertThat(fellowshipOfTheRing) .hasSize(9) .contains(frodo, sam) .doesNotContain(sauron);

Les exemples ci-dessus ne sont que la pointe de l'iceberg, mais nous donnent un aperçu de ce à quoi pourrait ressembler l'écriture d'assertions avec cette bibliothèque.

4. AssertJ en action

Dans cette section, nous allons nous concentrer sur la configuration d'AssertJ et explorer ses possibilités.

4.1. Commencer

Avec le fichier jar de la bibliothèque sur un chemin de classe, l'activation des assertions est aussi simple que l'ajout d'une seule importation statique à votre classe de test:

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

4.2. Rédaction d'assertions

Pour écrire une assertion, vous devez toujours commencer par passer votre objet à la méthode Assertions.assertThat () , puis vous devez suivre les assertions réelles.

Il est important de se rappeler que contrairement à certaines autres bibliothèques, le code ci-dessous n'affirme encore rien et n'échouera jamais à un test:

assertThat(anyRefenceOrValue);

Si vous tirez parti des fonctionnalités de complétion de code de votre IDE, l'écriture d'assertions AssertJ devient incroyablement facile en raison de ses méthodes très descriptives. Voici à quoi cela ressemble dans IntelliJ IDEA 16:

Fonctionnalités de complétion de code de l'IDE

Comme vous pouvez le voir, vous avez le choix entre des dizaines de méthodes contextuelles et celles-ci ne sont disponibles que pour le type String . Explorons en détail certaines de ces API et examinons certaines assertions spécifiques.

4.3. Assertions d' objets

Les objets peuvent être comparés de différentes manières, soit pour déterminer l'égalité de deux objets, soit pour examiner les champs d'un objet.

Regardons deux façons de comparer l'égalité de deux objets. Étant donné les deux objets Dog suivants , fido et fidosClone :

public class Dog { private String name; private Float weight; // standard getters and setters } Dog fido = new Dog("Fido", 5.25); Dog fidosClone = new Dog("Fido", 5.25);

Nous pouvons comparer l'égalité avec l'assertion suivante:

assertThat(fido).isEqualTo(fidosClone);

Cela échouera car isEqualTo () compare les références d'objets. Si nous voulons comparer leur contenu à la place, nous pouvons utiliser isEqualToComparingFieldByFieldRecursively () comme ceci:

assertThat(fido).isEqualToComparingFieldByFieldRecursively(fidosClone);

Fido et fidosClone sont égaux lors d'une comparaison de champ récursif par champ car chaque champ d'un objet est comparé au champ de l'autre objet.

Il existe de nombreuses autres méthodes d'assertion qui fournissent différentes manières de comparer et de contracter des objets et d'examiner et d'affirmer sur leurs champs. Pour les découvrir tous, reportez-vous à la documentation officielle de AbstractObjectAssert .

4.4. Assertions booléennes

Certaines méthodes simples existent pour tester la vérité:

  • est vrai()
  • c'est faux()

Voyons-les en action:

assertThat("".isEmpty()).isTrue();

4.5. Iterable/Array Assertions

For an Iterable or an Array there are multiple ways of asserting that their content exist. One of the most common assertions would be to check if an Iterable or Array contains a given element:

List list = Arrays.asList("1", "2", "3"); assertThat(list).contains("1");

or if a List is not empty:

assertThat(list).isNotEmpty();

or if a List starts with a given character. For example “1”:

assertThat(list).startsWith("1");

Keep in mind that if you want to create more than one assertion for the same object, you can join them together easily.

Here is an example of an assertion that checks if a provided list is not empty, contains “1” element, does not contains any nulls and contains sequence of elements “2”, “3”:

assertThat(list) .isNotEmpty() .contains("1") .doesNotContainNull() .containsSequence("2", "3");

Of course many more possible assertions exist for those types. In order to discover them all, refer to the official AbstractIterableAssert documentation.

4.6. Character Assertions

Assertions for character types mostly involve comparisons and even checking if a given character is from a Unicode table.

Here is an example of an assertion that checks if a provided character is not ‘a', is in Unicode table, is greater than ‘b' and is lowercase:

assertThat(someCharacter) .isNotEqualTo('a') .inUnicode() .isGreaterThanOrEqualTo('b') .isLowerCase();

For a detailed list of all character types' assertions, see AbstractCharacterAssert documentation.

4.7. Class Assertions

Assertions for Class type are mostly about checking its fields, Class types, presence of annotations and class finality.

If you want to assert that class Runnable is an interface, you need to simply write:

assertThat(Runnable.class).isInterface();

or if you want to check if one class is assignable from the other:

assertThat(Exception.class).isAssignableFrom(NoSuchElementException.class);

All possible Class assertions can be viewed in the AbstractClassAssert documentation.

4.8. File Assertions

File assertions are all about checking if a given File instance exists, is a directory or a file, has certain content, is readable, or has given extension.

Here you can see an example of an assertion that checks if a given file exists, is file and not a directory, can be readable and writable:

 assertThat(someFile) .exists() .isFile() .canRead() .canWrite();

All possible Class assertions can be viewed in the AbstractFileAssert documentation.

4.9. Double/Float/Integer Assertions

Double/Float/Integer and Other Number Types

Numeric assertions are all about comparing numeric values within or without a given offset. For example, if you want to check if two values are equal according to a given precision we can do the following:

assertThat(5.1).isEqualTo(5, withPrecision(1d));

Notice that we are using already imported withPrecision(Double offset) helper method for generating Offset objects.

For more assertions, visit AbstractDoubleAssert documentation.

4.10. InputStream Assertions

There is only one InputStream-specific assertion available:

  • hasSameContentAs(InputStream expected)

and in action:

assertThat(given).hasSameContentAs(expected);

4.11. Map Assertions

Map assertions allow you to check if a map contains certain entry, set of entries, or keys/values separately.

And here you can see an example of an assertions that checks if a given map is not empty, contains numeric key “2”, does not contain numeric key “10” and contains entry: key: 2, value: “a”:

assertThat(map) .isNotEmpty() .containsKey(2) .doesNotContainKeys(10) .contains(entry(2, "a"));

For more assertions, see AbstractMapAssert documentation.

4.12. Throwable Assertions

Throwable assertions allow for example: inspecting exception's messages, stacktraces, cause checking or verifying if an exception has been thrown already.

Let's have a look at the example of an assertion that checks if a given exception was thrown and has a message ending with “c”:

assertThat(ex).hasNoCause().hasMessageEndingWith("c");

For more assertions, see AbstractThrowableAssert documentation.

5. Describing Assertions

In order to achieve even higher verbosity level, you can create dynamically generated custom descriptions for your assertions. The key to doing this is the as(String description, Object… args) method.

If you define your assertion like this:

assertThat(person.getAge()) .as("%s's age should be equal to 100", person.getName()) .isEqualTo(100);

this is what you will get when running tests:

[Alex's age should be equal to 100] expected: but was:

6. Java 8

AssertJ tire pleinement parti des fonctionnalités de programmation fonctionnelle de Java 8. Plongeons dans un exemple et voyons-le en action. Voyons d'abord comment nous le faisons dans Java 7:

assertThat(fellowshipOfTheRing) .filteredOn("race", HOBBIT) .containsOnly(sam, frodo, pippin, merry);

Ici, nous filtrons une collection sur la race Hobbit et en Java 8, nous pouvons faire quelque chose comme ceci:

assertThat(fellowshipOfTheRing) .filteredOn(character -> character.getRace().equals(HOBBIT)) .containsOnly(sam, frodo, pippin, merry);

Nous explorerons les capacités Java8 d'AssertJ dans un prochain article de cette série. Les exemples ci-dessus ont été tirés du site Web d'AssertJ.

7. Conclusion

Dans cet article, nous avons brièvement exploré les possibilités qu'AssertJ nous offre ainsi que les assertions les plus populaires pour les types Java de base.

L'implémentation de tous les exemples et extraits de code se trouve dans un projet GitHub.

Suivant » AssertJ pour Guava