Einführung in AssertJ

Dieser Artikel ist Teil einer Reihe: • Einführung in AssertJ (aktueller Artikel) • AssertJ für Guave

• AssertJs Java 8-Funktionen

• Benutzerdefinierte Zusicherungen mit AssertJ

1. Übersicht

In diesem Artikel werden wir AssertJ untersuchen - eine OpenSource-Community-gesteuerte Bibliothek, die zum Schreiben fließender und umfangreicher Assertions in Java-Tests verwendet wird.

Dieser Artikel konzentriert sich auf Tools, die im AssertJ- Basismodul AssertJ-core verfügbar sind .

2. Maven-Abhängigkeiten

Um AssertJ verwenden zu können, müssen Sie den folgenden Abschnitt in Ihre pom.xml- Datei aufnehmen:

 org.assertj assertj-core 3.4.1 test  

Diese Abhängigkeit deckt nur die grundlegenden Java-Zusicherungen ab. Wenn Sie erweiterte Zusicherungen verwenden möchten, müssen Sie zusätzliche Module separat hinzufügen.

Beachten Sie, dass Sie für Java 7 und frühere Versionen AssertJ Core Version 2.xx verwenden sollten

Neueste Versionen finden Sie hier.

3. Einführung

AssertJ bietet eine Reihe von Klassen und Dienstprogrammmethoden, mit denen wir leicht fließende und schöne Aussagen schreiben können für:

  • Standard Java
  • Java 8
  • Guave
  • Joda Zeit
  • Neo4J und
  • Komponenten schwenken

Eine detaillierte Liste aller Module finden Sie auf der Website des Projekts.

Beginnen wir mit einigen Beispielen direkt aus der Dokumentation von 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);

Die obigen Beispiele sind nur die Spitze des Eisbergs, geben uns jedoch einen Überblick darüber, wie das Schreiben von Aussagen mit dieser Bibliothek aussehen könnte.

4. In Aktion behaupten

In diesem Abschnitt konzentrieren wir uns darauf, AssertJ einzurichten und seine Möglichkeiten zu erkunden.

4.1. Anfangen

Wenn sich das JAR der Bibliothek in einem Klassenpfad befindet, ist das Aktivieren von Zusicherungen so einfach wie das Hinzufügen eines einzelnen statischen Imports zu Ihrer Testklasse:

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

4.2. Behauptungen schreiben

Um eine Zusicherung zu schreiben, müssen Sie immer zunächst Ihr Objekt an die Assertions.assertThat () -Methode übergeben und anschließend die tatsächlichen Zusicherungen eingeben.

Es ist wichtig, sich daran zu erinnern, dass der folgende Code im Gegensatz zu einigen anderen Bibliotheken noch nichts bestätigt und niemals einen Test nicht bestehen wird:

assertThat(anyRefenceOrValue);

Wenn Sie die Code-Vervollständigungsfunktionen Ihrer IDE nutzen, wird das Schreiben von AssertJ-Zusicherungen aufgrund der sehr beschreibenden Methoden unglaublich einfach. So sieht es in IntelliJ IDEA 16 aus:

IDE-Funktionen zur Code-Vervollständigung

Wie Sie sehen können, stehen Ihnen Dutzende von Kontextmethoden zur Auswahl, die nur für den String- Typ verfügbar sind . Lassen Sie uns einige dieser APIs im Detail untersuchen und einige spezifische Aussagen betrachten.

4.3. Objekt Assertions

Objekte können auf verschiedene Arten verglichen werden, um entweder die Gleichheit zweier Objekte zu bestimmen oder um die Felder eines Objekts zu untersuchen.

Schauen wir uns zwei Möglichkeiten an, wie wir die Gleichheit zweier Objekte vergleichen können. In Anbetracht der folgenden zwei Hunde Objekte Fido und 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);

Wir können Gleichheit mit folgender Behauptung vergleichen:

assertThat(fido).isEqualTo(fidosClone);

Dies schlägt fehl, da isEqualTo () Objektreferenzen vergleicht. Wenn wir stattdessen ihren Inhalt vergleichen möchten, können wir isEqualToComparingFieldByFieldRecursively () wie folgt verwenden :

assertThat(fido).isEqualToComparingFieldByFieldRecursively(fidosClone);

Fido und fidosClone sind gleich, wenn ein rekursiver Feld-für-Feld-Vergleich durchgeführt wird, da jedes Feld eines Objekts mit dem Feld des anderen Objekts verglichen wird.

Es gibt viele andere Assertionsmethoden, die verschiedene Möglichkeiten bieten, Objekte zu vergleichen und zu kontrahieren sowie ihre Felder zu untersuchen und zu bestätigen. Informationen dazu finden Sie in der offiziellen AbstractObjectAssert- Dokumentation.

4.4. Boolesche Behauptungen

Es gibt einige einfache Methoden zum Testen der Wahrheit:

  • ist wahr()
  • ist falsch()

Lassen Sie uns sie in Aktion sehen:

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 nutzt die funktionalen Programmierfunktionen von Java 8 voll aus. Lassen Sie uns in ein Beispiel eintauchen und es in Aktion sehen. Lassen Sie uns zuerst sehen, wie wir es in Java 7 machen:

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

Hier filtern wir eine Sammlung nach dem Hobbit-Rennen und in Java 8 können wir so etwas tun:

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

Wir werden die Java8-Funktionen von AssertJ in einem zukünftigen Artikel aus dieser Reihe untersuchen. Die obigen Beispiele stammen von der Website von AssertJ.

7. Fazit

In diesem Artikel haben wir kurz die Möglichkeiten untersucht, die AssertJ uns bietet, sowie die beliebtesten Aussagen für Java-Kerntypen.

Die Implementierung aller Beispiele und Codefragmente finden Sie in einem GitHub-Projekt.

Weiter » AssertJ für Guave