Jak mogę zapewnić równość między listami w przypadku testowym JUnit ? Treść listy powinna być równa.
Na przykład:
List<String> numbers = Arrays.asList("one", "two", "three");
List<String> numbers2 = Arrays.asList("one", "two", "three");
List<String> numbers3 = Arrays.asList("one", "two", "four");
// numbers should be equal to numbers2
//numbers should not be equal to numbers3
java
unit-testing
collections
junit
Kamal
źródło
źródło
assertArrayEquals
Obecnie lubię używać . Używaj w połączeniu zList#toArray
.assertArrayEquals
wymaga pobrania tablic z list. Możesz działać bezpośrednio na liście za pomocąassertIterableEquals
assertIterableEquals
dostępne dla jUnit5 @ThetaSinnerOdpowiedzi:
Zdaję sobie sprawę, że pytano o to kilka lat temu, prawdopodobnie wtedy nie było tej funkcji. Ale teraz łatwo to zrobić:
Jeśli masz najnowszą wersję Junit zainstalowaną z hamcrestem, po prostu dodaj następujące importy:
http://junit.org/junit4/javadoc/latest/org/junit/Assert.html#assertThat(T, org.hamcrest.Matcher)
http://junit.org/junit4/javadoc/latest/org/hamcrest/CoreMatchers.html
http://junit.org/junit4/javadoc/latest/org/hamcrest/core/Is.html
źródło
System.out.println(actual == expected);
zwróci wartość false, aleSystem.out.println(actual.equals(expected));
zwróci true..equals(..)
zamiast==
?Nie przekształcaj w ciąg i nie porównuj. To nie jest dobre dla wydajności. W junit, wewnątrz Corematchers, znajduje się dopasowanie do this =>
hasItems
Jest to lepszy sposób, jaki znam, do sprawdzania elementów na liście.
źródło
Assert.assertEquals(4,yourList.size());
assertThat(yourList.toArray(), arrayContainingInAnyOrder(1,2,3,4,5));
toString()
oczywiście porównywanie łańcuchów poprzez ich wersję nie jest najlepszym sposobem.To jest starsza odpowiedź, odpowiednia dla JUnit 4.3 i starszych. Nowoczesna wersja JUnit zawiera wbudowane czytelne komunikaty o błędach w metodzie assertThat. Jeśli to możliwe, wolę inne odpowiedzi na to pytanie.
Dla przypomnienia, jak @Paul wspomniał w swoim komentarzu do tej odpowiedzi, dwa
List
s są równe:Zobacz dokumentację JavaDocs
List
interfejsu .źródło
assertEquals(Object, Object)
z JUnit4 / JUnit 5 lubassertThat(actual, is(expected));
z Hamcrest zaproponowane w innych odpowiedziach będą działać tylko jako obaequals()
itoString()
są nadpisywane dla klas (i głęboko) porównywanych obiektów.Ma to znaczenie, ponieważ test równości w asercji opiera się,
equals()
a komunikat o niepowodzeniu testu opiera siętoString()
na porównywanych obiektach.Dla wbudowanych klas, takich jak
String
,Integer
i tak za ... nie ma problemu, ponieważ te zastępują zarównoequals()
itoString()
. Tak więc jest to całkowicie słuszne, aby twierdzićList<String>
lubList<Integer>
zassertEquals(Object,Object)
.A jeśli chodzi o tę sprawę: musisz nadpisać
equals()
w klasie, ponieważ ma to sens z punktu widzenia równości obiektów, a nie tylko po to, aby ułatwić asercje w teście z JUnit.Aby ułatwić asercje, masz inne sposoby.
Jako dobrą praktykę preferuję biblioteki asercji / dopasowań.
Oto rozwiązanie AssertJ .
org.assertj.core.api.ListAssert.containsExactly()
jest tym, czego potrzebujesz: sprawdza, czy aktualna grupa zawiera dokładnie podane wartości i nic więcej, w kolejności określonej w javadoc.Załóżmy
Foo
klasę, w której dodajesz elementy i gdzie możesz to uzyskać.Test jednostkowy,
Foo
który potwierdza, że obie listy mają taką samą zawartość, mógłby wyglądać następująco:Dobrą stroną AssertJ jest to, że deklarowanie a
List
zgodnie z oczekiwaniami jest niepotrzebne: sprawia, że stwierdzenie jest prostsze, a kod bardziej czytelny:Ale biblioteki Assertion / Matcher są koniecznością, ponieważ będą naprawdę dalej.
Załóżmy teraz, że
Foo
nie przechowuje instancjiString
s aleBar
s.To bardzo powszechna potrzeba. Dzięki AssertJ twierdzenie jest nadal łatwe do napisania. Lepiej możesz stwierdzić, że zawartość listy jest równa, nawet jeśli klasa elementów nie nadpisuje,
equals()/hashCode()
podczas gdy sposób JUnit wymaga, aby:źródło
Jeśli nie zależy Ci na kolejności elementów, polecam
ListAssert.assertEquals
w junit-addons.Link: http://junit-addons.sourceforge.net/
Dla leniwych użytkowników Maven:
źródło
Możesz użyć assertEquals w junit .
Jeśli kolejność elementów jest inna, zwróci błąd.
źródło
jeśli nie chcesz tworzyć listy tablic, możesz spróbować również tego
źródło
źródło
Nie odkrywaj na nowo koła!
Jest biblioteka Google Code, która robi to za Ciebie: Hamcrest
źródło
Wiem, że istnieje już wiele opcji rozwiązania tego problemu, ale wolałbym wykonać następujące czynności, aby potwierdzić dwie listy w dowolnej odrze :
źródło
assertEquals(expected, result);
pracuje dla mnie. Ponieważ ta funkcja pobiera dwa obiekty, możesz przekazać do niej wszystko.źródło
Nie rozumiem, wszystkie powyższe odpowiedzi dają dokładne rozwiązanie do porównania dwóch list Obiektów. Większość z powyższych podejść może być pomocna tylko w przestrzeganiu limitu porównań - Porównanie wielkości - Porównanie referencyjne
Ale jeśli mamy listy obiektów tej samej wielkości i różne dane na poziomie obiektów, to podejście porównawcze nie pomoże.
Myślę, że następujące podejście będzie doskonale działać z zastępowaniem równości i metody hashcode na obiekcie zdefiniowanym przez użytkownika.
Użyłem Xstream lib do zastępowania równości i hashcode, ale możemy zastąpić równa się i hashcode również za pomocą wygranej logiki / porównania.
Oto przykład w celach informacyjnych
Najważniejsze jest to, że możesz zignorować pola przez Adnotację (@XStreamOmitField), jeśli nie chcesz uwzględniać żadnych pól w równym sprawdzeniu obiektów. Istnieje wiele takich adnotacji do skonfigurowania, więc zapoznaj się dokładnie z adnotacjami w tej bibliotece.
Jestem pewien, że ta odpowiedź pozwoli Ci zaoszczędzić czas na zidentyfikowanie właściwego podejścia do porównania dwóch list obiektów :). Prosimy o komentarz, jeśli zauważysz jakiekolwiek problemy z tym związane.
źródło