Sprawdzanie, czy lista nie jest pusta w Hamcrest

147

Zastanawiałem się, czy ktoś znał sposób sprawdzenia, czy lista jest pusta za pomocą assertThat()i Matchers?

Najlepszy sposób, w jaki mogłem zobaczyć, po prostu użyj JUnit:

assertFalse(list.isEmpty());

Miałem jednak nadzieję, że w Hamcrest da się to zrobić.

Ian Dallas
źródło
2
Aby uzyskać lepsze rozwiązanie, zagłosuj na: code.google.com/p/hamcrest/issues/detail?id=97
Fabricio Lemos
2
Wydaje się, że @FabricioLemos problem # 97 został rozwiązany i został połączony z głównym oddziałem git. Miejmy nadzieję, że nastąpi to wkrótce w następnym wydaniu hamcrestu.
rafalmag
@rafalmag Dobre miejsce. Dobrze będzie naprawić wszystkie moje niezbyt czytelne stwierdzenia, kiedy zostanie wydana
wersja 1.3

Odpowiedzi:

165

Cóż, zawsze jest

assertThat(list.isEmpty(), is(false));

... ale domyślam się, że nie do końca to miałeś na myśli :)

Alternatywnie:

assertThat((Collection)list, is(not(empty())));

empty()jest statyczny w Matchersklasie. Zwróć uwagę na potrzebę rzucenia listdo Collection, dzięki dziwacznym genom Hamcrest 1.2.

Następujący import może być używany z hamcrestem 1.3

import static org.hamcrest.Matchers.empty;
import static org.hamcrest.core.Is.is;
import static org.hamcrest.core.IsNot.*;
skaffman
źródło
6
Uważam, że kod Hamcresta wygląda o wiele ładniej, jeśli zmienisz podświetlanie składni, aby nawiasy były niewidoczne ...
skaffman
2
@ tkeE2036: To zepsute generiki Hamcresta w pracy. Czasami trzeba wykonać rzut, aby się skompilował, np.assertThat((Collection)list, is(not(empty())));
skaffman
7
Naprawiono to w 1.3
artbristol
14
@dzieciou daje lepszy komunikat o błędzie, gdy test się nie powiedzie. Więc zamiast expected true but got falseciebie dostajesz coś takiegoexpected empty but got [1, 2, 3]
Brad Cupit
3
Jeśli wolisz brak niekontrolowanej konwersji i chcesz zrezygnować z importu statycznego, możesz dodać assertThat(list, Matchers.<String>empty())String
typy ogólne
77

Naprawiono to w Hamcrest 1.3. Poniższy kod kompiluje się i nie generuje żadnych ostrzeżeń:

// given
List<String> list = new ArrayList<String>();
// then
assertThat(list, is(not(empty())));

Ale jeśli musisz użyć starszej wersji - zamiast zbugowanej empty()możesz użyć:

hasSize(greaterThan(0))
( import static org.hamcrest.number.OrderingComparison.greaterThan;lub
import static org.hamcrest.Matchers.greaterThan;)

Przykład:

// given
List<String> list = new ArrayList<String>();
// then
assertThat(list, hasSize(greaterThan(0)));

Najważniejsze w powyższych rozwiązaniach jest to, że nie generuje żadnych ostrzeżeń. Drugie rozwiązanie jest jeszcze bardziej przydatne, jeśli chcesz oszacować minimalną wielkość wyniku.

rafalmag
źródło
1
@rogerdpack Proszę bardzo. Dodałem przykład stylu 1.3. :)
rafalmag
1
Pamiętaj, że assertThat(list, not(hasSize(0)))będzie udany , jeśli listjest null, w przeciwieństwie doassertThat(list, hasSize(greaterThan(0)))
José Andias
5

Jeśli szukasz czytelnych wiadomości o niepowodzeniach, możesz obejść się bez hamcrest, używając zwykłych assertEquals z pustą listą:

assertEquals(new ArrayList<>(0), yourList);

Np. Jeśli biegniesz

assertEquals(new ArrayList<>(0), Arrays.asList("foo", "bar");

dostajesz

java.lang.AssertionError
Expected :[]
Actual   :[foo, bar]
kamczak
źródło
2
Naprawdę miło jest zobaczyć, co zostało na rzekomo pustej liście!
HDave
0

Utwórz własny, niestandardowy IsEmpty TypeSafeMatcher:

Nawet jeśli problemy generyczne zostały rozwiązane, 1.3wielką zaletą tej metody jest to, że działa ona na każdej klasie, która ma isEmpty()metodę! Nie tylko Collections!

Na przykład to też zadziała String!

/* Matches any class that has an <code>isEmpty()</code> method
 * that returns a <code>boolean</code> */ 
public class IsEmpty<T> extends TypeSafeMatcher<T>
{
    @Factory
    public static <T> Matcher<T> empty()
    {
        return new IsEmpty<T>();
    }

    @Override
    protected boolean matchesSafely(@Nonnull final T item)
    {
        try { return (boolean) item.getClass().getMethod("isEmpty", (Class<?>[]) null).invoke(item); }
        catch (final NoSuchMethodException e) { return false; }
        catch (final InvocationTargetException | IllegalAccessException e) { throw new RuntimeException(e); }
    }

    @Override
    public void describeTo(@Nonnull final Description description) { description.appendText("is empty"); }
}
Społeczność
źródło
0

To działa:

assertThat(list,IsEmptyCollection.empty())
Richard
źródło