2013-03-25 10 views
31

Jak sprawdzić za pomocą Hamcrest, czy podana kolekcja zawiera podane pozycje w podanej kolejności? Próbowałem hasItems, ale po prostu ignoruje kolejność.Jak sprawdzić, czy kolekcja zawiera przedmioty w podanej kolejności przy użyciu Hamcrestu

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

Rozważ zmianę akceptowanej odpowiedzi. Zazwyczaj, gdy wyszukujemy element dopasowujący, preferujemy te już w interfejsie API, pozostawiając niestandardowe dopasowania w nieuniknionych przypadkach. – acdcjunior

+0

Masz rację! Dzięki –

+1

Przyjęta odpowiedź nie odpowiada na pytanie. Pytanie wymaga dopasowania, które jedynie sprawdza, czy oczekiwane elementy są zawarte w rzeczywistej liście w podanej kolejności, ale nie, że są to WSZYSTKIE rzeczywiste pozycje. Metoda 'Matchers.contains' sprawdza, czy lista zawiera dokładnie oczekiwane elementy. –

Odpowiedz

40

Można użyć contains dopasowywania zamiast, ale prawdopodobnie trzeba używać najnowszej wersji Hamcrest. Ta metoda sprawdza zamówienie.

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

Możesz także spróbować użyć containsInAnyOrder, jeśli zamówienie nie ma dla ciebie znaczenia.

To kod contains dopasowującego:

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

+1 Tak, zaktualizuj najnowsze JUnit i Hamcrest, chociaż "zawiera" już od jakiegoś czasu. –

+1

Jaką wersję Hamcrest? Dla mnie 1.3 powoduje: java.lang.AssertionError: Oczekiwano: Iterable zawierające ["foo", "boo"] , ale: Niezgodne: "bar" –

+1

rozwiązanie nie będzie działać dla danego podzbioru lista wyników, ponieważ zawiera-Matcher kończy się niepowodzeniem z dodatkowym elementem, który nie jest podany w oczekiwanej tablicy elementów. – vvursT

3

Trzeba wdrożyć niestandardowy Matcher, coś w tym

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

Twój kod nigdy się nie zwrócił - poprawiłem to. –

+2

OMG. Ten matcher jest brzydki i wadliwy. Powinno to rozszerzyć TypeSafeMatcher.Lub najmniej sprawdzaj instancję elementu w metodach match() - obecnie możesz uzyskać ClassCastExecption. I powinien to być typ ogólny, ponieważ obecnie działa tylko dla ciągów. I powinien obsługiwać wartość null. A dopasowania() mają złożoność O (n^2). I ... – Marek

1

Przyjęte rozwiązanie nie działa dla mnie. To nadal nie mówiąc

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

Więc napisałem własną IsIterableContainingInRelativeOrder i submitted it as a patch.

-1

znalazłem rozwiązanie w http://www.baeldung.com/hamcrest-collections-arrays

Znajdź sekcję, która ma przykład ze ścisłej kolejności.

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

Zasadniczo trzeba użyć zawiera Matcher (org.hamcrest.Matchers.contains)

+3

Witamy w przepełnieniu stosu. W tym przypadku lepiej jest umieścić w odpowiedzi ważne części kodu. – AliLotfi

1

Aby sprawdzić tha kolekcja zawiera elementy w oczekiwanej (danego) Aby można wykorzystać metodę Hamcrest containsInRelativeOrder użytkownika.

Z 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")).

Rzeczywista Java Hamcrest 2.0.0.0.

Mam nadzieję, że to pomoże.

Powiązane problemy