Pytanie Hamcrest porównuje kolekcje


Próbuję porównać 2 listy:

assertThat(actual.getList(), is(Matchers.containsInAnyOrder(expectedList)));

Ale pomysł

java: no suitable method found for assertThat(java.util.List<Agent>,org.hamcrest.Matcher<java.lang.Iterable<? extends model.Agents>>)
method org.junit.Assert.<T>assertThat(T,org.hamcrest.Matcher<T>) is not applicable
  (no instance(s) of type variable(s) T exist so that argument type org.hamcrest.Matcher<java.lang.Iterable<? extends model.Agents>> conforms to formal parameter type org.hamcrest.Matcher<T>)
method org.junit.Assert.<T>assertThat(java.lang.String,T,org.hamcrest.Matcher<T>) is not applicable
  (cannot instantiate from arguments because actual and formal argument lists differ in length)

Jak mam to napisać?


76
2018-02-07 10:00


pochodzenie




Odpowiedzi:


Jeśli chcesz potwierdzić, że te dwie listy są identyczne, nie komplikuj rzeczy z Hamcrestem:

assertEquals(expectedList, actual.getList());

Jeśli naprawdę chcesz wykonać porównanie niewrażliwe na zamówienie, możesz zadzwonić do containsInAnyOrder Metoda varargs i podaj wartości bezpośrednio:

assertThat(actual.getList(), containsInAnyOrder("item1", "item2"));

(Zakładając, że twoja lista jest z Stringraczej niż Agent, dla tego przykładu.)

Jeśli naprawdę chcesz wywołać tę samą metodę z zawartością a List:

assertThat(actual.getList(), containsInAnyOrder(expectedList.toArray(new String[expectedList.size()]));

Bez tego wywołujesz metodę jednym argumentem i tworzysz Matcher który oczekuje dopasowania Iterable gdzie każdy element jest List. Nie można tego użyć do dopasowania a List.

Oznacza to, że nie można dopasować a List<Agent> z a Matcher<Iterable<List<Agent>>, właśnie tego próbuje twój kod.


118
2018-02-07 13:21



+1 dla "Jeśli naprawdę chcesz wywołać tę samą metodę z zawartością listy". Niestety nie mogłem sam tego rozwiązać. Szczególnie, że istnieje konstruktor pobierający kolekcję. - Eyad Ebrahim
@Tim Niezupełnie; containsInAnyOrder wymaga tego wszystko elementy są obecne, więc pierwsze stwierdzenie się nie powiedzie. Widzieć hasItems jeśli chcesz to sprawdzić przynajmniej te elementy są obecne. - Joe
tak masz rację - Tim
Jeśli używasz programu NotesInAnyOrder, najpierw upewnij się, że obie listy mają ten sam rozmiar ... Jeśli actual.getList() zdarza się zawierać "item1", "item3", "item2", test przejdzie, a może chcesz się upewnić, że zawiera tylko wymienione pozycje ... W takim przypadku możesz użyć assertThat(actual.getList().size(), equalTo(2)); przed containsInAnyOrder, w ten sposób upewniasz się, że obie listy mają tę samą zawartość. - Martin
@Martin, o którym myślisz hasItems. Dodatkowa kontrola jest tutaj niepotrzebna. Zobacz komentarz do Tima powyżej, a także Jak różnią się hasItems, zawiera i zawiera InAnyOrder w Hamcrest? - Joe


Jedyną rzeczą, którą chcę dodać do odpowiedzi Joe Joe jest to, że toArray() Parametr jest tutaj nadmiarowy, więc możesz napisać porównanie niewrażliwe na porządki w następujący sposób:

List<Long> actual = Arrays.asList(1L, 2L);
List<Long> expected = Arrays.asList(2L, 1L);
assertThat(actual, containsInAnyOrder(expected.toArray()));

33
2018-03-01 03:25



Czy nie powinien to być komentarz? - Tim


Aby uzupełnić odpowiedź @ Joe'a:

Hamcrest oferuje trzy główne metody dopasowania listy:

contains Sprawdza, czy pasuje do wszystkich elementów biorących udział w liczeniu zleceń, jeśli lista zawiera więcej lub mniej elementów, to się nie powiedzie

containsInAnyOrder Sprawdza, czy pasują wszystkie elementy i nie ma znaczenia kolejność, jeśli lista ma więcej lub mniej elementów, zawiedzie

hasItems Sprawdza tylko dla określonych obiektów nie ma znaczenia, czy lista ma więcej

hasItem Sprawdza tylko jeden obiekt, nie ma znaczenia, czy lista ma więcej

Wszyscy mogą otrzymać listę obiektów i użyć equals metoda porównywania lub może być mieszana z innymi akcesoriami, takimi jak @borjab:

assertThat(myList , contains(allOf(hasProperty("id", is(7L)), 
                                   hasProperty("name", is("testName1")),
                                   hasProperty("description", is("testDesc1"))),
                             allOf(hasProperty("id", is(11L)), 
                                   hasProperty("name", is("testName2")),
                                   hasProperty("description", is("testDesc2")))));

http://hamcrest.org/JavaHamcrest/javadoc/1.3/org/hamcrest/Matchers.html#contains (E ...) http://hamcrest.org/JavaHamcrest/javadoc/1.3/org/hamcrest/Matchers.html#containsInAnyOrder(java.util.Collection) http://hamcrest.org/JavaHamcrest/javadoc/1.3/org/hamcrest/Matchers.html#hasItems (T ...)


10
2018-05-17 16:40



Trochę spóźniony na imprezę, ale dzięki za opis różnic między poszczególnymi metodami. - Marcos de Andrade


W istniejących bibliotekach Hamcrena (od wersji 2.0.0.0) jesteś zmuszony do używania metody Collection.toArray () w swojej Kolekcji, aby móc korzystać z metody includeInAnyOrder Matcher. Bardziej przyjemne byłoby dodanie tego jako osobnej metody do org.hamcrest.Matchers:

public static <T> org.hamcrest.Matcher<java.lang.Iterable<? extends T>> containsInAnyOrder(Collection<T> items) {
    return org.hamcrest.collection.IsIterableContainingInAnyOrder.<T>containsInAnyOrder((T[]) items.toArray());
}

Właściwie to w końcu dodałem tę metodę do mojej niestandardowej biblioteki testowej i używam jej do zwiększenia czytelności moich przypadków testowych (z powodu mniejszej szczegółowości).


6
2017-07-08 08:57



Niezła, wykorzystam tego pomocnika. Wiadomość assert tutaj jest bardziej pouczająca: nazwy brakujących elementów jeden po drugim, nie tylko: lista powinna być elem1, elem2, .. elem99, ale mam elem1, elem2, ..., elem98 - powodzenia znalezienie brakującego. - pihentagy


Aby wyświetlić listę obiektów, możesz potrzebować czegoś takiego:

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.beans.HasPropertyWithValue.hasProperty;
import static org.hamcrest.Matchers.is;

@Test
@SuppressWarnings("unchecked")
public void test_returnsList(){

    arrange();

    List<MyBean> myList = act();

    assertThat(myList , contains(allOf(hasProperty("id",          is(7L)), 
                                       hasProperty("name",        is("testName1")),
                                       hasProperty("description", is("testDesc1"))),
                                 allOf(hasProperty("id",          is(11L)), 
                                       hasProperty("name",        is("testName2")),
                                       hasProperty("description", is("testDesc2")))));
}

Posługiwać się zawieraInAnyOrder jeśli nie chcesz sprawdzać kolejności obiektów.

P.S. Każda pomoc, aby uniknąć ostrzeżenia, które jest suppresed będzie naprawdę docenione.


1
2018-03-09 19:00





Upewnij się, że Objectna liście masz equals() zdefiniowane na nich. Następnie

    assertThat(generatedList,is(equalTo(expectedList)));

Prace.


1
2017-10-12 16:47



Działa to również z tablicami - Will Humphreys


Aby porównać dwie listy z zachowanym porządkiem,

assertThat(actualList, contains("item1","item2"));

-3
2017-11-11 17:28



To nie odpowiada na pytanie. - kamczak
Po części to robi. - rvazquezglez
@rvazquezglez Co masz na myśli? Dlaczego to mówisz? Wynik tej metody jest właściwy w moim środowisku. - niaomingjian
@kamczak Czy kod nie może porównać dwóch list? - niaomingjian
@niaomingjian Kod sprawdza, czy actualList zawiera elementy wewnątrz contains matcher, które zawiodą, jeśli elementy nie są w tej samej kolejności i ulegną uszkodzeniu, jeśli zawiera więcej elementów lub ich brakuje. - rvazquezglez