AssertJ - Listen

Aus MimiPedia

Listen, Arrays, Kollektionen

Besonders hilfreich ist AssertJ bei der Prüfung von Listen aller Art. Sehr angenehm ist dabei die gleichartige Behandlung von Typen wie Streams, Arrays und Collections wie List und Set die alle mit den gleichen Methoden getestet werden. Das bedeutet, daß weniger Methoden zu lernen sind und wenn sich der Typ eines Ausdrucks ändert -- z.B. von List nach Stream -- muß der Test nicht angepaßt werden.

Das Einfachste ist die Suche nach bestimmten Werten:

Assertions.assertThat(liste).contains("x", "y");

Die Prüfung gelingt, wenn die Liste -- gegebenenfalls neben anderen Strings -- die String "x" und "y" an beliebiger Stelle enthält. Daneben gibt es eine ganze Legion von contains-Methoden wie z.B.

containsAnyOf
containsExactly
containsExactlyInAnyOrder
containsNull
containsOnly

Analog dazu giebt es negierte Methoden, die mit doesNotContain beginnen.

Bei simplen Typen wie String oder Zahlen funktionieren die contains-Methoden sehr gut. Bei Objekten wird für den Vergleich die .equals-Methode verwendet und wenn die nicht passend implementiert wurde, erhält man unbefriedigende Ergebnisse.

Läßt sich der Test durch ein Prädikat -- eine Funktion die ein Objekt übernimmt und einen bool-Wert liefert -- beschreiben, kann man λ-Prädikate verwenden um prüfen, ob ein Objekt (anyMatch) oder alle Objekte (noneMatch ) der Liste die Eigenschaft haben.

Möchten wir etwa sicherstellen, daß die Liste ein Objekt mit der ID "5" enthält, könnte das so aussehen:

Assertions.assertThat(liste).anyMatch(x -> x.id().equals(5));

in Objekte hineinschauen

Oft ist es ausreichend ein einzelnes Attribut der Objekte in der Liste zu kontrollieren. Während man bei simplen Typen einfach eine Vergleichsliste angiebt, muß man bei Objekten erst das ebtsprechende Attribut herausholen oder extrahieren. Möchten wir etwa bei einer Liste von Personen die Namen kontrollieren, können wir das mit extracting so machen:

Assertions.assertThat(liste)
    .extracting(Person::getVorname)
    .contains("Otto", "Paul", "Frieda);

Die Methode extracting bekommt als Argument einen λ-Ausdruck der auf die Objekte der Liste angewendet wird. Giebt man mehrere λ-Ausdrücke mit, erzeugt extracting eine Liste von Tupeln. Das Ergebnis kann dann wieder mit den contains-Methoden geprüft werden:

Assertions.assertThat(liste)
    .extracting(Person::getVorname, Person::getNachname) //
    .contains(tupel("Otto", "Krause"),
              tupel("Paul", "Anka"),
              tupel("Frieda", "Kahlo"));

Die Methode tuple ist eine statische Methode der Klasse Tuple im Package org.assertj.core.groups und erzeugt aus den Argumenten der Liste ein sie enthaltendes Objekt -- ein Tupel. Der Lesbarkeit halber wurde die Methode hier statisch importiert.

Übersicht der Test-Methoden

Die folgende Tabelle bietet einen Überblick über die Test-Methoden, die AssertJ für Listen anbietet. Die Tabelle ist nicht vollständig, läßt insbesondere die oben beschriebenen contains-Methoden aus. Als Listen-Beispiel wird hier List<X> verwendet, X ist dabei ein beliebiger Java-Typ.

Test negierter Test Parameter
all/anyMatch noneMatch Predicate<X>
all/anySatisfy noneSatisfy Consumer<X>
are,have areNot,doNotHave Condition<X>
matches Predicate<List<X>>
satisfies Consumer<List<X>>
has,is,satisfies doesNotHave Condition<List<X>>

Conditions werden hier beschrieben.

Wie man sieht, testen die ersten drei Methoden-Gruppen die Listen-Elemente, während die letzten drei die Liste als Objekt -- quasi in ihrer Gesamtheit -- testet.

Nicht alle Methoden haben Negationen, in jedem Falle kann man das mit einem negierten λ-Ausdruck erreichen.

Ist der Parameter ein Consumer, wird erwartet, daß dieser Assertions enthält, andernfalls testet die Assertion nichts. In allen anderen Fällen führt AssertJ die Assertion aus.