Vérifier qu'une liste n'est pas vide dans Hamcrest

147

Je me demandais si quelqu'un connaissait un moyen de vérifier si une liste est vide en utilisant assertThat()et Matchers?

La meilleure façon que je pourrais voir utiliser JUnit:

assertFalse(list.isEmpty());

Mais j'espérais qu'il y avait un moyen de faire cela à Hamcrest.

Ian Dallas
la source
2
Pour une meilleure solution, votez pour: code.google.com/p/hamcrest/issues/detail?id=97
Fabricio Lemos
2
@FabricioLemos issue # 97 semble être résolu et fusionné pour maîtriser la branche git. Espérons que ce sera bientôt dans la prochaine version de Hamcrest.
rafalmag
@rafalmag Bon endroit. Ce sera bien de corriger toutes mes affirmations pas si lisibles lors de la sortie de la v1.3
andyb

Réponses:

165

Eh bien, il y a toujours

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

... mais je suppose que ce n'est pas tout à fait ce que vous vouliez dire :)

Alternativement:

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

empty()est un statique dans la Matchersclasse. Notez la nécessité de lancer le listto Collection, grâce aux génériques loufoques de Hamcrest 1.2.

Les importations suivantes peuvent être utilisées avec hamcrest 1.3

import static org.hamcrest.Matchers.empty;
import static org.hamcrest.core.Is.is;
import static org.hamcrest.core.IsNot.*;
skaffman
la source
6
Je trouve que le code Hamcrest semble beaucoup plus agréable si vous modifiez votre coloration syntaxique pour rendre les parenthèses invisibles ...
skaffman
2
@ tkeE2036: Ce sont les génériques cassés de Hamcrest au travail. Parfois, vous devez lancer un casting pour le compiler, par exempleassertThat((Collection)list, is(not(empty())));
skaffman
7
Ceci est corrigé dans la version 1.3
artbristol
14
@dzieciou cela vous donne un meilleur message d'erreur lorsque le test échoue. Donc au lieu de expected true but got falsevous obtenez quelque chose commeexpected empty but got [1, 2, 3]
Brad Cupit
3
Si vous ne préférez aucune conversion non vérifiée et que vous êtes prêt à abandonner l'importation statique, vous pouvez ajouter les génériques à la méthode, comme: assertThat(list, Matchers.<String>empty())(en supposant que la liste est une collection de Strings)
earcam
77

Ceci est corrigé dans Hamcrest 1.3. Le code ci-dessous se compile et ne génère aucun avertissement:

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

Mais si vous devez utiliser une version plus ancienne - au lieu de bugger, empty()vous pouvez utiliser:

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

Exemple:

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

La chose la plus importante à propos des solutions ci-dessus est qu'elles ne génèrent aucun avertissement. La deuxième solution est encore plus utile si vous souhaitez estimer la taille minimale des résultats.

rafalmag
la source
1
@rogerdpack Ici vous allez. J'ai ajouté l'exemple de style 1.3. :)
rafalmag
1
Méfiez-vous que assertThat(list, not(hasSize(0)))cela réussira si listc'est null, par opposition àassertThat(list, hasSize(greaterThan(0)))
José Andias
5

Si vous recherchez des messages d'échec lisibles, vous pouvez vous passer de hamcrest en utilisant les assertEquals habituels avec une liste vide:

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

Par exemple, si vous exécutez

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

vous obtenez

java.lang.AssertionError
Expected :[]
Actual   :[foo, bar]
kamczak
la source
2
C'est vraiment sympa de voir ce qui restait dans la liste supposément vide!
HDave
0

Créez votre propre IsEmpty TypeSafeMatcher personnalisé:

Même si les problèmes génériques sont résolus dans 1.3le grand avantage de cette méthode, c'est qu'elle fonctionne sur n'importe quelle classe qui a une isEmpty()méthode! Pas seulement Collections!

Par exemple, cela fonctionnera Stringaussi!

/* 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"); }
}
Communauté
la source
0

Cela marche:

assertThat(list,IsEmptyCollection.empty())
Richard
la source