CollectionAssert in jUnit?

Antworten:

125

Mit JUnit 4.4 können Sie assertThat()zusammen mit dem Hamcrest- Code (keine Sorge, er wird mit JUnit geliefert , kein Extra erforderlich .jar) komplexe, selbstbeschreibende Asserts erstellen, einschließlich solcher, die Sammlungen bearbeiten :

import static org.junit.Assert.assertThat;
import static org.junit.matchers.JUnitMatchers.*;
import static org.hamcrest.CoreMatchers.*;

List<String> l = Arrays.asList("foo", "bar");
assertThat(l, hasItems("foo", "bar"));
assertThat(l, not(hasItem((String) null)));
assertThat(l, not(hasItems("bar", "quux")));
// check if two objects are equal with assertThat()

// the following three lines of code check the same thing.
// the first one is the "traditional" approach,
// the second one is the succinct version and the third one the verbose one 
assertEquals(l, Arrays.asList("foo", "bar")));
assertThat(l, is(Arrays.asList("foo", "bar")));
assertThat(l, is(equalTo(Arrays.asList("foo", "bar"))));

Mit diesem Ansatz erhalten Sie automatisch eine gute Beschreibung der Behauptung, wenn sie fehlschlägt.

Joachim Sauer
quelle
1
Oh, ich hatte nicht bemerkt, dass Hamcrest es in die Junit Distribution geschafft hatte. Geh Nat!
Skaffman
Wenn ich behaupten möchte, dass l aus Elementen besteht ("foo", "bar"), aber keine anderen Elemente vorhanden sind - gibt es dafür eine einfache Syntax?
Ripper234
Verwenden Sie den obigen Code - Schnipsel und wirft in einem zusätzlichen assertTrue (l.size () == 2)
aberrant80
4
Meh, hässlich. In NUnit ist das CollectionAssert.AreEqual (Sammlung erwartet, Sammlung aktuell);
Ripper234
1
Google hat eine andere Stackoverflow-Antwort gefunden, nach der ich gesucht habe!
Mykola Golubyev
4

Nicht direkt, nein. Ich schlage die Verwendung von Hamcrest vor , das eine Vielzahl von Übereinstimmungsregeln bietet, die sich gut in jUnit (und andere Test-Frameworks) integrieren lassen.

Skaffman
quelle
Dies wird aus irgendeinem Grund nicht kompiliert (siehe stackoverflow.com/questions/1092981/hamcrests-hasitems ): ArrayList <Integer> actual = new ArrayList <Integer> (); ArrayList <Integer> expected = new ArrayList <Integer> (); actual.add (1); erwartet.add (2); assertThat (actual, hasItems (erwartet));
Ripper234
2

Schauen Sie sich FEST Fluent Assertions an. IMHO sind sie bequemer zu bedienen als Hamcrest (und ebenso leistungsfähig, erweiterbar usw.) und haben dank fließender Benutzeroberfläche eine bessere IDE-Unterstützung. Siehe https://github.com/alexruiz/fest-assert-2.x/wiki/Using-fest-assertions

Tomek Kaczanowski
quelle
2017 scheinen mehr Menschen eine FEST-Niederlassung namens AssertJ zu nutzen.
Max
2

Die Lösung von Joachim Sauer ist nett, funktioniert aber nicht, wenn Sie bereits eine Reihe von Erwartungen haben, die Sie in Ihrem Ergebnis überprüfen möchten. Dies kann auftreten, wenn Sie in Ihren Tests bereits eine generierte oder konstante Erwartung haben, mit der Sie ein Ergebnis vergleichen möchten, oder wenn Sie mehrere Erwartungen haben, von denen Sie erwarten, dass sie im Ergebnis zusammengeführt werden. Anstatt also Matcher verwenden können Sie können einfach verwenden List::containsAllund assertTrueBeispiel:

@Test
public void testMerge() {
    final List<String> expected1 = ImmutableList.of("a", "b", "c");
    final List<String> expected2 = ImmutableList.of("x", "y", "z");
    final List<String> result = someMethodToTest(); 

    assertThat(result, hasItems(expected1)); // COMPILE ERROR; DOES NOT WORK
    assertThat(result, hasItems(expected2)); // COMPILE ERROR; DOES NOT WORK

    assertTrue(result.containsAll(expected1));  // works~ but has less fancy
    assertTrue(result.containsAll(expected2));  // works~ but has less fancy
}
gavs
quelle
Sie können immer verwenden hasItems(expected1.toArray(new String[expected1.size()])). Sie erhalten bessere Fehlermeldungen.
Meustrus