web-dev-qa-db-fra.com

Pourquoi ce code ne tente-t-il pas d'utiliser les hasItems de Hamcrest?

Pourquoi cela ne compile-t-il pas, oh, que faire?

import static org.junit.Assert.assertThat;
import static org.junit.matchers.JUnitMatchers.hasItems;

ArrayList<Integer> actual = new ArrayList<Integer>();
ArrayList<Integer> expected = new ArrayList<Integer>();
actual.add(1);
expected.add(2);
assertThat(actual, hasItems(expected));

erreur copiée du commentaire:

cannot find symbol method assertThat(Java.util.ArrayList<Java.lang.Integer>, org.hamcreset.Matcher<Java.lang.Iterable<Java.util.ArrayList<Java.lang.Integer>>>)
55
ripper234

Je suis juste tombé sur ce post en essayant de le réparer moi-même. M'a donné juste assez d'informations pour le résoudre.

Vous pouvez donner au compilateur juste assez pour le persuader de compiler en convertissant la valeur de retour de hasItems vers un Matcher (brut), par exemple:

ArrayList<Integer> actual = new ArrayList<Integer>();
ArrayList<Integer> expected = new ArrayList<Integer>();
actual.add(1);
expected.add(2);
assertThat(actual, (Matcher) hasItems(expected));

Juste au cas où quelqu'un d'autre souffrirait encore ...

Modifier pour ajouter: Malgré les votes positifs, cette réponse est fausse, comme le souligne Arend ci-dessous. La réponse correcte consiste à transformer l'attendu en un tableau d'entiers, comme l'attend hamcrest:

    ArrayList<Integer> actual = new ArrayList<Integer>();
    ArrayList<Integer> expected = new ArrayList<Integer>();
    actual.add(1);
    expected.add(2);
    assertThat(actual, hasItems(expected.toArray(new Integer[expected.size()])));
53
Clive Evans

hasItems vérifie qu'une collection contient certains éléments, pas que 2 collections sont égales, utilisez simplement les assertions d'égalité normales pour cela. Donc, assertEquals (a, b) ou en utilisant assertThat

import static org.junit.Assert.assertThat;
import static org.hamcrest.CoreMatchers.is;

ArrayList<Integer> actual = new ArrayList<Integer>();
ArrayList<Integer> expected = new ArrayList<Integer>();
actual.add(1);
expected.add(2);
assertThat(actual, is(expected));

Vous pouvez également utiliser le contient Matcher, qui vérifie qu'un Iterable contient des éléments dans un ordre spécifique

import static org.junit.Assert.assertThat;
import static org.hamcrest.Matchers.contains;

ArrayList<Integer> actual = new ArrayList<Integer>();
actual.add(1);
actual.add(2);
assertThat(actual, contains(1, 2)); // passes
assertThat(actual, contains(3, 4)); // fails

Si vous ne vous souciez pas de la commande, utilisez containsInAnyOrder à la place.

22
Dan Godfrey

Vous comparez ArrayList<Integer> avec int. La comparaison correcte est:

...
assertThat(actual, hasItem(2));

-- Modifier --

Je suis désolé, je l'ai mal lu. Quoi qu'il en soit, la signature de hasItems que vous souhaitez est:

public static <T> org.hamcrest.Matcher<Java.lang.Iterable<T>> hasItems(T... elements)

c'est-à-dire qu'il accepte un nombre variable d'arguments. Je ne sais pas si un ArrayList<T> est compatible, juste en devinant ici. Essayez d'envoyer chaque élément de la liste attendue entrecoupée de virgule.

assertThat(actual, hasItems(2,4,1,5,6));

- Modifier 2 -

En collant ici mon commentaire, il existe une expression équivalente pour ce que vous voulez, sans utiliser Hamcrest:

assertTrue(actual.containsAll(expected));
12
freitass

Essayer

assertThat(actual, hasItems(expected.toArray(new Integer[0])));

pour satisfaire la signature du matcher. Pas d'Eclipse autour, donc cela pourrait ne pas fonctionner.

3
Robert Munteanu

Vous pouvez obtenir cette erreur si vous essayez de remplacer le hamcrest de jUnit par une version plus récente. Par exemple, l'utilisation de junit-dep avec hamcrest 1.3 nécessite d'utiliser assertThat de hamcrest au lieu de jUnit.

La solution consiste donc à utiliser

import static org.hamcrest.MatcherAssert.assertThat;

au lieu de

import static org.junit.Assert.assertThat;

2
Mika

Je viens de rencontrer le même problème et l'astuce suivante a fonctionné pour moi:

  • utilisation import static org.hamcrest.Matchers.hasItems
  • avoir la bibliothèque hamcrest avant junit dans classpath (chemin de compilation -> ordre et exportation)
2
Zsolt

Ce message d'erreur ressemble à celui produit par le compilateur javac. J'ai trouvé dans le passé que le code écrit en utilisant hamcrest ne se compilera tout simplement pas sous javac. Le même code compilera très bien sous, disons, le compilateur Eclipse.

Je pense que les génériques de Hamcrest exercent des cas de coin dans des génériques que javac ne peut pas traiter.

2
skaffman

Dans ces cas, lorsque le code se compile dans Eclipse mais que javac affiche des erreurs, veuillez aider hamcrest en fournissant un paramètre de type explicite, par exemple Matchers.hasItem ()

1
miluch
ArrayList<Integer> expected = new ArrayList<Integer>();
expected.add(1);
expected.add(2);
hasItems(expected);

hasItems (T..t) est développé par le compilateur pour:

hasItems(new ArrayList<Integer>[]{expected});

Vous passez un tableau d'éléments unique contenant une ArrayList. Si vous changez ArrayList en tableau, votre code fonctionnera.

Integer[] expected = new Integer[]{1, 2};
hasItems(expected);

Cela sera étendu à:

hasItems(1, 2);
0
Matthew