2010-02-22 16 views
70

Come si afferma succintamente l'uguaglianza degli elementi collections, in particolare uno Set in JUnit 4?JUnit 4 confrontare le raccolte

+2

controllo questo SO inviare http://stackoverflow.com/questions/1086691/collectionassert-in-junit –

+0

Stai cercando di affermare che due Set sono uguali tra loro (contengono gli stessi elementi) o che due elementi dello stesso Set sono uguali? –

+0

Ho bisogno di vedere che gli elementi di due Set sono uguali – Eqbal

risposta

74

Si può solo affermare che i due set sono uguali tra loro, che invoca il Set equals() method.

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); 
    } 
} 

Questo test passerà se i due insiemi hanno la stessa dimensione e contengono gli stessi elementi.

+2

Funziona anche per la mappa. –

+4

Questo non mostra risultati molto buoni nel rapporto. Se le tue toString sono definite chiaramente è meglio, ma non va bene (una piccola differenza può finire con una pagina di testo) –

+0

Uhm, come mai ottengo: java.lang.AssertionError: expected: java.util.Hashtable <{ CompanyName = 8PKQ9va3nW8pRWb4SjPF2DvdQDBmlZ, Ric = sZwmXAdYKv, Categoria = AvrIfd, QuoteId = 4342740204922826921}> ma era: java.util.Hashtable <{CompanyName = 8PKQ9va3nW8pRWb4SjPF2DvdQDBmlZ, Ric = sZwmXAdYKv, Categoria = AvrIfd, QuoteId = 4342740204922826921}> –

10

con hamcrest:

assertThat(s1, is(s2)); 

con assert pianura:

assertEquals(s1, s2); 

NB: t i equals() metodo della calcestruzzo di classe insieme viene utilizzato

+0

Preferisco questo metodo dal momento che Hamcrest viene fornito con JUnit 4 quindi è tutto lì non c'è bisogno di altre librerie. – JRSofty

+1

Questo potrebbe non funzionare quando i set hanno tipi diversi. –

2

Controllare this article. Un esempio da 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); 
} 
+0

Link breve ma eccezionale, spiega molto velocemente cosa puoi fare con Junit4- – Johannes

+0

Il link è rotto. Qualche possibilità di trovare una versione archiviata online o di riassumere i suoi contenuti? – pzp

6

particolarmente caso interessante è quando si confrontano

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

e

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

Finora, l'unica soluzione che vedo è quella di cambiare entrambi in set

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

Oppure potrei confrontarli elemento per elemento.

+0

In realtà, ci sono diverse soluzioni per quella presentata nelle altre risposte. I set sono un po 'sfortunati per questo, comunque, dal momento che ignorano l'ordine. Forse ArrayList? –

29

Apache commons al salvataggio di nuovo.

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

Funziona come un fascino. Non so perché, ma ho trovato che con le collezioni il seguente assertEquals(coll1, coll2) non funziona sempre. Nel caso in cui abbia fallito, avevo due collezioni supportate da Sets. Né hamcrest né junit direbbero che le collezioni erano uguali anche se sapevo per certo che lo erano. Utilizzando CollectionUtils funziona perfettamente.

+14

Questo è in realtà banale, la parte difficile è indicare chiaramente la differenza al chiamante –

+1

La risposta accettata è una buona risposta per la domanda originale (unit test specifico per due Set) ma questa risposta con CollectionUtils è una risposta migliore per il caso più generale. Non sono stato in grado di confrontare una raccolta e un set senza utilizzare CollectionUtils. – Jay

4

Come metodo aggiuntivo basato su array ... è possibile considerare l'utilizzo di asserzioni di array non ordinati in junitx. Anche se l'esempio Apache CollectionUtils funziona, c'è un pacakge di estensioni affermazione solidi anche lì:

Penso che l'approccio

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

sarà molto più leggibile e debuggable per voi (tutte le collezioni supportano toArray(), quindi dovrebbe essere abbastanza semplice usare i metodi ArrayAssert

Ovviamente il lato negativo qui è che junitx è un file jar aggiuntivo o una voce di controllo ...

<dependency org="junit-addons" name="junit-addons" rev="1.4"/> 
0

Se si desidera controllare se un elenco o insieme contiene un insieme di valori specifici (invece di confrontare con una collezione già esistente), spesso il metodo toString delle collezioni è a portata di mano:

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

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

Questo è un po 'più corto di prima la costruzione della collezione prevista e la sua comparazione con la raccolta effettiva, e più facile da scrivere e correggere.

(Certo, questo non è un metodo particolarmente pulito, e non è possibile distinguere un elemento "foo, bar" da due elementi "foo" e "bar". Ma in pratica penso che sia più importante che sia facile e veloce per scrivere i test, altrimenti molti sviluppatori semplicemente non senza essere premuto)

+0

Ciò rende il risultato del test dell'unità dipendente dall'implementazione di toString dall'elenco. Se decidono di cambiare la formattazione, il test dell'unità non funzionerà più. Non lo considererei sicuro. –

+0

@ LaurensOp'tZandt Intendi Oracle che modifica il formato di Collection.toList()? Certamente non succederà. Hai, comunque, ragione che non è particolarmente pulito. Ma in pratica, la mia impressione è che è molto più facile scrivere test. –

+0

Sono d'accordo, penso che il metodo toString non abbia possibilità. Quindi probabilmente continuerà a funzionare. Volevo solo sottolineare che non è un modo molto pulito. Ma in effetti è molto facile. Un problema che si pone è quando si confrontano gli insiemi. Dal momento che il loro ordine non è garantito. –

2

Utilizzando Hamcrest:.

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

Questo funziona anche quando gli insiemi hanno diversi tipi di dati, e le relazioni sulla differenza invece di solo in mancanza di .

+1

Qual è l'importazione per isIn? IntelliJ non può risolvere l'importazione con alcun pacchetto hamcret. – fabien

0

Mi piace la soluzione di Hans-Peter Störr ... Ma penso che non sia del tutto corretto. Purtroppo containsInAnyOrder non accetta uno Collection di oggetti da confrontare. Così deve essere un Collection di Matcher s:

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

L'importazione sono:

import static java.util.stream.Collectors.toList; 
import static org.hamcrest.Matchers.containsInAnyOrder; 
import static org.junit.Assert.assertThat; 
Problemi correlati