2009-07-07 14 views
54

Warum kompiliert das nicht, oh, was zu tun ist?Warum versucht dieser Code nicht, hasItems von Hamcrest zu kompilieren?

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

Fehler von Kommentar kopiert:

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

Antwort

12

Sie sind ArrayList<Integer> mit int zu vergleichen. Der richtige Vergleich ist:

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

- Bearbeiten -

Es tut mir leid, ich habe es falsch gelesen. Wie auch immer, die Signatur von hasItems Sie wollen, ist:

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

heißt es akzeptiert eine variable Anzahl von Argumenten. Ich bin mir nicht sicher, ob eine ArrayList<T> kompatibel ist, nur hier raten. Versuchen Sie, jedes Element aus der erwarteten Liste mit Komma zu senden.

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

- Edit 2 -

Genau hier mein Kommentar einfügen, ist es ein Äquivalent Ausdruck für das, was Sie wollen, ohne Verwendung von hamcrest:

assertTrue(actual.containsAll(expected)); 
+0

Ich vergleiche mehrere Artikel zu verwenden. (hasItems, not hasItem) – ripper234

+0

Also, hamcrest unterstützt einfach nicht den Vergleich zweier Sammlungen? (Ich habe keine tatsächliche Liste von Elementen, ich baue die Liste der Zahlen von 0 bis 999 Ich muss Sammlungen vergleichen). – ripper234

+0

Ich kann das nicht für Sie beantworten, ich erzähle das anhand der Dokumentation. Aber es gibt einen einfacheren Weg, um das zu tun, was Sie wollen ... benutze assertTrue (actual.containsAll (expected)). – freitass

2

Diese Fehlermeldung wie man sieht erzeugt vom javac-Compiler. Ich habe in der Vergangenheit festgestellt, dass Code, der mit hamcrest geschrieben wurde, nicht unter javac kompiliert wird. Derselbe Code wird beispielsweise unter dem Eclipse-Compiler kompiliert.

Ich denke, dass Hamcrests Generika Eckfälle in Generika ausüben, mit denen Javac nicht umgehen kann.

+0

Wow, interessant. Sie sagen also, der obige Code ist legitimer Java-Code? – ripper234

+2

Nein, ich sage, dass Javaac manchmal legitimen Java-Code ablehnt, und Hamcrest ist eine häufige Ursache dafür. – skaffman

3

Versuchen

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

die Matcher Unterschrift zu befriedigen. Keine Eclipse herum, also könnte das nicht funktionieren.

21

hasItems überprüft, ob eine Sammlung einige Elemente enthält, nicht, dass 2 Sammlungen gleich sind, verwenden Sie einfach die normalen Gleichheitserklärungen dafür. Also entweder assertEquals (a, b) oder mit 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)); 

Alternativ können Sie das Matcher enthält, die überprüft, ob ein Iterable enthält Elemente in einer bestimmten Reihenfolge

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 

Wenn Sie nicht über egal die Bestellung verwendet stattdessen containsInAnyOrder.

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

HasItems (t..t) vom Compiler wird, um erweitert:

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

Sie passieren Array ein einzelnes Element eine Arraylist enthält. Wenn Sie die ArrayList in ein Array ändern, funktioniert Ihr Code.

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

Dies wird erweitert: Für diese Fälle

hasItems(1, 2); 
1

, wenn Code in Eclipse nicht kompiliert aber Javac zeigt Fehler Hilfe hamcrest tun, indem sie explizit eingeben Bereitstellung Parameter bitte z.B. Matchers.hasItem()

2

Ich kam in dem gleichen Problem und der folgende Trick funktionierte für mich:

  • Verwendung import static org.hamcrest.Matchers.hasItems
  • haben die hamcrest Bibliothek vor junit in Classpath (Pfad bauen -> bestellen und exportieren)
52

Gerade lief in diesen Beitrag versucht, es für mich selbst zu beheben. Gab mir gerade genug Informationen, um es auszuarbeiten.

Sie können die Compiler nur genug geben, es zu überzeugen, durch Gießen des Rückgabewertes von HasItems zu einem (raw) Matcher, zum Beispiel zu kompilieren:

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

Für den Fall, jemand anderes leidet immer noch ...

Zu fügen hinzufügen: Trotz der oben Abstimmungen ist diese Antwort falsch, wie Arend unten zeigt. Die richtige Antwort ist der erwartete in ein Array von ganzen Zahlen zu drehen, wie hamcrest erwartet:

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()]))); 
+0

Ich habe diese Antwort nicht getestet, da ich vor langer Zeit diesen Quellcode verloren habe (Firmen zweimal verschoben), aber ich habe dir einen Daumen gegeben, um das wieder aufleben zu lassen. – ripper234

+1

Guter Tipp. Scheint der einzige "einfache" Weg, um assetThat() mit jeder Sammlung Matcher seit Hamcrest ihre Sammlung Matcher Generika zu anstelle von nur .. – Frans

+0

geändert. Ich wünschte, 'hasItems' auch die Reihenfolge abgestimmt. Was scheint es nicht. –

2

Sie diesen Fehler erhalten, wenn Sie versuchen, JUnit hamcrest mit einer neueren Version zu ersetzen. Zum Beispiel erfordert die Verwendung von junit-dep zusammen mit hamcrest 1.3, dass assertThat von hamcrest anstelle von jUnit verwendet wird.

So ist die Lösung

import static org.hamcrest.MatcherAssert.assertThat;

statt

import static org.junit.Assert.assertThat;