web-dev-qa-db-fra.com

Hamcrest compare les collections

J'essaie de comparer 2 listes:

assertThat(actual.getList(), is(Matchers.containsInAnyOrder(expectedList)));

Mais idée

Java: no suitable method found for assertThat(Java.util.List<Agent>,org.hamcrest.Matcher<Java.lang.Iterable<? extends model.Agents>>)
method org.junit.Assert.<T>assertThat(T,org.hamcrest.Matcher<T>) is not applicable
  (no instance(s) of type variable(s) T exist so that argument type org.hamcrest.Matcher<Java.lang.Iterable<? extends model.Agents>> conforms to formal parameter type org.hamcrest.Matcher<T>)
method org.junit.Assert.<T>assertThat(Java.lang.String,T,org.hamcrest.Matcher<T>) is not applicable
  (cannot instantiate from arguments because actual and formal argument lists differ in length)

Comment devrais-je l'écrire?

95
xander27

Si vous voulez affirmer que les deux listes sont identiques, ne compliquez pas les choses avec Hamcrest:

assertEquals(expectedList, actual.getList());

Si vous souhaitez réellement effectuer une comparaison insensible à la commande, vous pouvez appeler la méthode containsInAnyOrder varargs et fournir directement les valeurs suivantes:

assertThat(actual.getList(), containsInAnyOrder("item1", "item2"));

(En supposant que votre liste soit de String, plutôt que Agent, pour cet exemple.)

Si vous voulez vraiment appeler cette même méthode avec le contenu d'un List:

assertThat(actual.getList(), containsInAnyOrder(expectedList.toArray(new String[expectedList.size()]));

Sans cela, vous appelez la méthode avec un seul argument et créez une Matcher supposée correspondre à un Iterablechaque élément est un List. Cela ne peut pas être utilisé pour faire correspondre un List.

Autrement dit, vous ne pouvez pas associer un List<Agent> à un Matcher<Iterable<List<Agent>>, ce que tente votre code.

141
Joe
List<Long> actual = Arrays.asList(1L, 2L);
List<Long> expected = Arrays.asList(2L, 1L);
assertThat(actual, containsInAnyOrder(expected.toArray()));

Version plus courte de la réponse de @ Joe sans paramètres redondants.

52
Jofsey

Pour compléter la réponse de @ Joe:

Hamcrest vous propose trois méthodes principales pour apparier une liste:

contains Vérifie la correspondance de tous les éléments prenant en compte l'ordre. Si la liste contient plus ou moins d'éléments, elle échouera.

containsInAnyOrder Vérifie la correspondance de tous les éléments et peu importe l'ordre, si la liste contient plus ou moins d'éléments, échouera

hasItems Vérifie uniquement les objets spécifiés, peu importe si la liste en contient plus

hasItem Vérifie seulement un objet, peu importe si la liste en contient plus

Chacun d'entre eux peut recevoir une liste d'objets et utiliser la méthode equals pour la comparaison ou peut être mélangé avec d'autres correspondants tels que @borjab mentionné:

assertThat(myList , contains(allOf(hasProperty("id", is(7L)), 
                                   hasProperty("name", is("testName1")),
                                   hasProperty("description", is("testDesc1"))),
                             allOf(hasProperty("id", is(11L)), 
                                   hasProperty("name", is("testName2")),
                                   hasProperty("description", is("testDesc2")))));

http://hamcrest.org/JavaHamcrest/javadoc/1.3/org/hamcrest/Matchers.html#contains (E ...)http://hamcrest.org/JavaHamcrest/ javadoc/1.3/org/hamcrest/Matchers.html # includesInAnyOrder (Java.util.Collection)http://hamcrest.org/JavaHamcrest/javadoc/1.3/org/hamcrest/Matchers.html#hasItems (T ...)

18
rvazquezglez

Avec les bibliothèques Hamcrest existantes (à partir de la v.2.0.0.0), vous êtes obligé d'utiliser la méthode Collection.toArray () sur votre Collection pour pouvoir utiliser includesInAnyOrder Matcher. Il serait beaucoup plus agréable d'ajouter ceci comme méthode distincte à org.hamcrest.Matchers:

public static <T> org.hamcrest.Matcher<Java.lang.Iterable<? extends T>> containsInAnyOrder(Collection<T> items) {
    return org.hamcrest.collection.IsIterableContainingInAnyOrder.<T>containsInAnyOrder((T[]) items.toArray());
}

En fait, j'ai fini par ajouter cette méthode à ma bibliothèque de tests personnalisée et à l'utiliser pour améliorer la lisibilité de mes scénarios de test (en raison de moins de verbosité).

9
yvolk

Assurez-vous que Objects dans votre liste a défini equals(). ensuite

    assertThat(generatedList,is(equalTo(expectedList)));

travaux.

3
Jim Jarrett

Pour une liste d'objets, vous pouvez avoir besoin de quelque chose comme ceci:

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.beans.HasPropertyWithValue.hasProperty;
import static org.hamcrest.Matchers.is;

@Test
@SuppressWarnings("unchecked")
public void test_returnsList(){

    arrange();

    List<MyBean> myList = act();

    assertThat(myList , contains(allOf(hasProperty("id",          is(7L)), 
                                       hasProperty("name",        is("testName1")),
                                       hasProperty("description", is("testDesc1"))),
                                 allOf(hasProperty("id",          is(11L)), 
                                       hasProperty("name",        is("testName2")),
                                       hasProperty("description", is("testDesc2")))));
}

Utilisez includesInAnyOrder si vous ne souhaitez pas vérifier l'ordre des objets.

P.S. Toute aide pour éviter l’avertissement supprimé sera vraiment appréciée.

1
borjab