2013-03-25 5 views
31

Wie überprüft man Hamcrest, wenn die Sammlung bestimmte Artikel in der angegebenen Reihenfolge enthält? Ich habe versucht hasItems, aber es ignoriert einfach die Reihenfolge.Wie überprüft man, ob die Sammlung Artikel in der angegebenen Reihenfolge enthält, mit Hamcrest

List<String> list = Arrays.asList("foo", "bar", "boo"); 

assertThat(list, hasItems("foo", "boo")); 

//I want this to fail, because the order is different than in "list" 
assertThat(list, hasItems("boo", "foo")); 
+1

Überlegen Sie, die akzeptierte Antwort zu ändern. Wenn wir nach einem Matcher suchen, bevorzugen wir in der Regel diejenigen, die bereits in der API enthalten sind, sodass benutzerdefinierte Matcher den unvermeidlichen Fällen überlassen werden. – acdcjunior

+0

Sie haben Recht! Danke –

+1

Die angenommene Antwort beantwortet die Frage nicht. Die Frage fragt nach einem Matcher, der lediglich prüft, ob die erwarteten Artikel in der tatsächlichen Liste in der angegebenen Reihenfolge enthalten sind, aber nicht, dass dies ALLE tatsächlichen Artikel sind. Die Methode 'Matchers.contains' überprüft, ob die Liste genau die erwarteten Elemente enthält. –

Antwort

40

können Sie contains Matcher verwenden statt, aber Sie müssen wahrscheinlich neueste Version von hamcrest verwenden. Diese Methode überprüft die Reihenfolge.

assertThat(list, contains("foo", "boo")); 

können Sie auch versuchen, containsInAnyOrder verwenden, wenn bestellen Sie spielt keine Rolle.

, dass der Code für contains Matcher ist:

public static <E> Matcher<Iterable<? extends E>> contains(List<Matcher<? super E>> itemMatchers) 
    { 
    return IsIterableContainingInOrder.contains(itemMatchers); 
    } 
+1

+1 Ja, update auf die neuesten JUnit und Hamcrest, obwohl 'contains 'gibt es schon seit einer Weile. –

+1

Welche Version von Hamcrest? Für mich 1.3 verursacht: java.lang.AssertionError: Erwartet: iterable enthält [ "foo", "Boo"] aber: Nicht abgestimmt: "bar" –

+1

die Lösung wird für eine bestimmte Teilmenge nicht arbeiten von Die Ergebnisliste, weil contains-Matcher mit einem zusätzlichen Element fehlschlägt, das nicht im erwarteten Elementarray angegeben ist. – vvursT

3

Sie benötigen eine benutzerdefinierte Matcher, so etwas wie dieses

class ListMatcher extends BaseMatcher { 
    String[] items; 

    ListMatcher(String... items) { 
     this.items = items; 
    } 

    @Override 
    public boolean matches(Object item) { 
     List list = (List) (item); 
     int l = -1; 
     for (String s : items) { 
      int i = list.indexOf(s); 
      if (i == -1 || i < l) { 
       return false; 
      } 
      l = i; 
     } 
     return true; 
    } 

    @Override 
    public void describeTo(Description description) { 
     // not implemented 
    } 
} 

@Test 
public void test1() { 
    List<String> list = Arrays.asList("foo", "bar", "boo"); 
    Assert.assertThat(list, new ListMatcher("foo", "boo")); 
    Assert.assertThat(list, new ListMatcher("boo", "foo")); 
} 
+0

Ihr Code ist nie wieder wahr - das habe ich korrigiert. –

+2

OMG. Dieser Matcher ist hässlich und fehlerhaft. Es sollte TypeSafeMatcher erweitern.Oder überprüfen Sie die Instanz des Elements in den matches() -Methoden - derzeit können Sie ClassCastException abrufen. Und es sollte ein generischer Typ sein, weil es momentan nur für Strings funktioniert. Und es sollte mit Null umgehen. Und die Matches() haben O (n^2) -Komplexität. Und ... – Marek

1

Die akzeptierte Antwort für mich nicht funktioniert zu implementieren. Es ist immer noch, sagte

Expected: iterable containing ["foo", "boo"] but: Not matched: "bar" 

Also ich meinen eigenen IsIterableContainingInRelativeOrder schreibe, und submitted it as a patch.

-1

fand ich eine Lösung bei http://www.baeldung.com/hamcrest-collections-arrays

Suchen Sie den Abschnitt, der ein Beispiel mit strengen Ordnung hat.

List<String> collection = Lists.newArrayList("ab", "cd", "ef"); 
assertThat(collection, contains("ab", "cd", "ef")); 

Grundsätzlich müssen Sie das enthält Matcher (org.hamcrest.Matchers.contains)

+3

Willkommen bei Stack Overflow. Hier ist es besser, wichtige Teile des Codes in Ihre Antwort aufzunehmen. – AliLotfi

1

Um zu überprüfen, tha Kollektionsteile verwenden, enthält der erwarteten (gegeben), um Sie hamcrest des containsInRelativeOrder Methode verwenden können.

Von javadoc:

Creates a matcher for Iterable's that matches when a single pass over the examined Iterable yields a series of items, that contains items logically equal to the corresponding item in the specified items, in the same relative order For example: assertThat(Arrays.asList("a", "b", "c", "d", "e"), containsInRelativeOrder("b", "d")).

Actual für Java hamcrest 2.0.0.0.

Hoffe, das hilft.

Verwandte Themen