CollectionAssert w jUnit?

Odpowiedzi:

125

Używając JUnit 4.4, możesz używać assertThat()razem z kodem Hamcrest (nie martw się, jest dostarczany z JUnit, nie ma potrzeby dodatkowego .jar) do tworzenia złożonych samoopisujących potwierdzeń, w tym tych, które działają na kolekcjach:

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"))));

Korzystając z tego podejścia, automagicznie uzyskasz dobry opis potwierdzenia, gdy zawiedzie.

Joachim Sauer
źródło
1
Ooh, nie zdawałem sobie sprawy, że hamcrest trafił do dystrybucji junit. Idź Nat!
skaffman
Jeśli chcę potwierdzić, że l składa się z elementów („foo”, „bar”), ale innych elementów nie ma - czy istnieje na to jakaś prosta składnia?
ripper234
Użyj powyższego fragmentu kodu i wrzuć dodatkowe assertTrue (l.size () == 2)
aberrant80
4
Meh, brzydki. W NUnit to CollectionAssert.AreEqual (kolekcja oczekiwana, kolekcja rzeczywista);
ripper234
1
Google znalazło inną odpowiedź Stackoverflow, której szukałem!
Mykoła Golubyev
4

Nie bezpośrednio, nie. Sugeruję użycie Hamcrest , który zapewnia bogaty zestaw reguł dopasowywania, który ładnie integruje się z jUnit (i innymi frameworkami testowymi)

skaffman
źródło
Z jakiegoś powodu to się nie kompiluje (patrz stackoverflow.com/questions/1092981/hamcrests-hasitems ): ArrayList <Integer> current = new ArrayList <Integer> (); ArrayList <Integer> spodziewane = new ArrayList <Integer> (); rzeczywiste.add (1); spodziewany.add (2); assertThat (rzeczywiste, hasItems (oczekiwane));
ripper234
2

Rozwiązanie Joachima Sauera jest fajne, ale nie działa, jeśli masz już szereg oczekiwań, które chcesz zweryfikować. Może się tak zdarzyć, gdy masz już wygenerowane lub stałe oczekiwanie w swoich testach, z którym chcesz porównać wynik, lub być może masz wiele oczekiwań, które spodziewasz się scalić w wyniku. Więc zamiast korzystać z dopasowań, możesz po prostu użyć List::containsAlli assertTrueNa przykład:

@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
źródło
Zawsze możesz użyć hasItems(expected1.toArray(new String[expected1.size()])). Zapewni lepsze komunikaty o błędach.
meustrus