JUnit 4 comparer les Collections

Comment affirmeriez-vous succinctement l'égalité des éléments collections, en particulier un Set dans JUnit 4?

81
demandé sur Rodrigo 2010-02-22 21:42:08

9 réponses

Vous pouvez simplement affirmer que les deux ensembles sont égaux l'un à l'autre, ce qui appelle la méthode Set equals () .

public class SimpleTest {

    private Set<String> setA;
    private Set<String> setB;

    @Before
    public void setUp() {
        setA = new HashSet<String>();
        setA.add("Testing...");
        setB = new HashSet<String>();
        setB.add("Testing...");
    }

    @Test
    public void testEqualSets() {
        assertEquals( setA, setB );
    }
}

Ce test réussira si les deux ensembles ont la même taille et contiennent les mêmes éléments.

83
répondu Bill the Lizard 2010-02-22 19:08:51

Apache commons à nouveau à la rescousse.

assertTrue(CollectionUtils.isEqualCollection(coll1, coll2));

Fonctionne comme un charme. Je ne sais pas pourquoi mais j'ai trouvé qu'avec les collections, le assertEquals(coll1, coll2) suivant ne fonctionne pas toujours. Dans le cas où cela a échoué pour moi, j'avais deux collections soutenues par des ensembles. Ni hamcrest ni junit ne diraient que les collections étaient égales même si je savais avec certitude qu'elles l'étaient. En utilisant CollectionUtils cela fonctionne parfaitement.

32
répondu Matt Friedman 2015-04-09 08:58:46

Avec hamcrest:

assertThat(s1, is(s2));

Avec simple assert:

assertEquals(s1, s2);

NB: T la méthode equals() de la classe concrete set est utilisée

11
répondu dfa 2010-02-22 18:55:38

Un cas particulièrement intéressant est lorsque vous comparez

   java.util.Arrays$ArrayList<[[name,value,type], [name1,value1,type1]]> 

Et

   java.util.Collections$UnmodifiableCollection<[[name,value,type], [name1,value1,type1]]>

Jusqu'à présent, la seule solution que je vois est de les changer tous les deux en ensembles

assertEquals(new HashSet<CustomAttribute>(customAttributes), new HashSet<CustomAttribute>(result.getCustomAttributes()));

Ou je pourrais les comparer élément par élément.

7
répondu Arkadiy 2010-08-30 19:44:47

Comme une méthode supplémentaire basée sur un tableau ... vous pouvez envisager d'utiliser des assertions de tableau non ordonnées dans junitx . Bien que L'exemple Apache CollectionUtils fonctionne, il existe également un pacakge d'extensions d'assertion solides:

Je pense que le

ArrayAssert.assertEquivalenceArrays(new Integer[]{1,2,3}, new Integer[]{1,3,2});

L'approche sera beaucoup plus lisible et déboguable pour vous (toutes les Collections supportent toArray (), il devrait donc être assez facile d'utiliser les méthodes ArrayAssert.

Bien sûr, l'inconvénient ici est que, junitx est un fichier JAR supplémentaire ou une entrée maven...

 <dependency org="junit-addons" name="junit-addons" rev="1.4"/>
4
répondu jayunit100 2012-03-19 16:48:51

Vérifier cet article. Un exemple à partir de là:

@Test  
public void listEquality() {  
    List<Integer> expected = new ArrayList<Integer>();  
    expected.add(5);  

    List<Integer> actual = new ArrayList<Integer>();  
    actual.add(5);  

    assertEquals(expected, actual);  
}  
2
répondu Roman 2010-02-22 18:58:23

En Utilisant Hamcrest:

assertThat( set1, both(everyItem(isIn(set2))).and(containsInAnyOrder(set1)));

Cela fonctionne également lorsque les ensembles ont des types de données différents, et signale la différence au lieu d'échouer.

1
répondu Hans-Peter Störr 2017-08-21 07:11:53

Si vous voulez vérifier si une liste ou un ensemble contient un ensemble de valeurs spécifiques (au lieu de le comparer avec une collection déjà existante), la méthode ToString des collections est souvent pratique:

String[] actualResult = calltestedmethod();
assertEquals("[foo, bar]", Arrays.asList(actualResult).toString());

List otherResult = callothertestedmethod();
assertEquals("[42, mice]", otherResult.toString());

C'est un peu plus court que de construire d'abord la collection attendue et de la comparer avec la collection réelle, et plus facile à écrire et à corriger.

(Certes, ce n'est pas une méthode particulièrement propre, et ne peut pas distinguer un élément "foo, bar" de deux éléments "foo" et "bar". Mais en pratique, je pense qu'il est le plus important qu'il soit facile et rapide d'écrire des tests, sinon de nombreux développeurs ne le feront pas sans être pressés.)

0
répondu Hans-Peter Störr 2017-03-25 07:09:37

J'aime la solution de Hans-Peter Störr... Mais je pense que ce n'est pas tout à fait correct. Malheureusement, containsInAnyOrder n'accepte pas un Collection d'objets à comparer. Donc, il doit être un Collection de Matchers:

assertThat(set1, containsInAnyOrder(set2.stream().map(IsEqual::equalTo).collect(toList())))

Les importations sont:

import static java.util.stream.Collectors.toList;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.junit.Assert.assertThat;
0
répondu FLUXparticle 2018-01-14 11:10:14