Perché questo codice che tenta di utilizzare gli hasItem di Hamcrest non viene compilato?

Perché questo non è compilato, oh, cosa fare?

import static org.junit.Assert.assertThat; import static org.junit.matchers.JUnitMatchers.hasItems; ArrayList actual = new ArrayList(); ArrayList expected = new ArrayList(); actual.add(1); expected.add(2); assertThat(actual, hasItems(expected)); 

errore copiato dal commento:

 cannot find symbol method assertThat(java.util.ArrayList, org.hamcreset.Matcher<java.lang.Iterable<java.util.ArrayList>>) 

Mi sono imbattuto in questo post cercando di sistemarlo da solo. Mi ha dato abbastanza informazioni per risolverlo.

Puoi dare al compilatore quel tanto che basta per convincerlo a compilare lanciando il valore di ritorno da hasItem a un Matcher (grezzo), ad esempio:

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

Nel caso in cui qualcun altro stia ancora soffrendo …

Modifica per aggiungere: nonostante i voti positivi, questa risposta è sbagliata, come indicato da Arend in seguito. La risposta corretta è trasformare l’attesa in una serie di numeri interi, come ci si aspetta hamcrest:

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

hasItems verifica che una collezione contenga alcuni elementi, non che 2 collezioni siano uguali, basta usare le normali asserzioni di uguaglianza per quello. Quindi assertEquals (a, b) o using assertThat

 import static org.junit.Assert.assertThat; import static org.hamcrest.CoreMatchers.is; ArrayList actual = new ArrayList(); ArrayList expected = new ArrayList(); actual.add(1); expected.add(2); assertThat(actual, is(expected)); 

In alternativa, usa il Matcher che controlla che un Iterable contenga elementi in un ordine specifico

 import static org.junit.Assert.assertThat; import static org.hamcrest.Matchers.contains; ArrayList actual = new ArrayList(); actual.add(1); actual.add(2); assertThat(actual, contains(1, 2)); // passes assertThat(actual, contains(3, 4)); // fails 

Se non ti interessa l’ordine, usa invece InAnyOrder.

Stai confrontando ArrayList con int . Il confronto corretto è:

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

— Modificare —

Mi dispiace, ho letto male. Ad ogni modo, la firma di hasItems che vuoi è:

 public static  org.hamcrest.Matcher> hasItems(T... elements) 

cioè, accetta un numero variabile di argomenti. Non sono sicuro che un ArrayList sia compatibile, solo indovinando qui. Prova a inviare ogni elemento dall’elenco previsto intervallato dalla virgola.

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

– Modifica 2 –

Basta incollare qui il mio commento, c’è un’espressione equivalente per quello che vuoi, senza usare Hamcrest:

 assertTrue(actual.containsAll(expected)); 

Provare

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

per soddisfare la firma del matcher. No Eclipse in giro, quindi potrebbe non funzionare.

Quel messaggio di errore sembra uno prodotto dal compilatore javac. Ho trovato in passato che il codice scritto usando hamcrest non verrà compilato sotto javac. Lo stesso codice verrà compilato correttamente, ad esempio, nel compilatore Eclipse.

Penso che i generici di Hamcrest stiano esercitando casi angosciosi in generici che javac non può affrontare.

Ho appena incontrato lo stesso problema e il seguente trucco ha funzionato per me:

  • usa import static org.hamcrest.Matchers.hasItems
  • avere la libreria hamcrest prima di junit in classpath (percorso build -> ordine ed esportazione)

È ansible ottenere questo errore se si tenta di sostituire hamcrest di jUnit con una versione più recente. Ad esempio, utilizzando junit-dep insieme a hamcrest 1.3 è necessario utilizzare assertThat da hamcrest anziché jUnit.

Quindi la soluzione è da usare

import static org.hamcrest.MatcherAssert.assertThat;

invece di

import static org.junit.Assert.assertThat;

Per questi casi, quando il codice viene compilato in Eclipse ma javac mostra errori, si prega di aiutare hamcrest fornendo un parametro di tipo esplicito, ad esempio Matchers.hasItem ()

 ArrayList expected = new ArrayList(); expected.add(1); expected.add(2); hasItems(expected); 

hasItems (T..t) viene espanso dal compilatore per:

 hasItems(new ArrayList[]{expected}); 

Stai passando un singolo array di elementi contenente un ArrayList. Se si modifica ArrayList in una matrice, il codice funzionerà.

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

Questo sarà esteso a:

 hasItems(1, 2);