JUnit 4 Vergleiche Sets

102

Wie würden Sie die Gleichheit der CollectionElemente, insbesondere a Setin JUnit 4, kurz und bündig behaupten ?

Gl
quelle
2
Überprüfen Sie diese SO post stackoverflow.com/questions/1086691/collectionassert-in-junit
Teja Kantamneni
Versuchen Sie zu behaupten, dass zwei Mengen gleich sind (dieselben Elemente enthalten) oder dass zwei Elemente derselben Menge gleich sind?
Bill the Lizard
Ich muss sehen, dass die Elemente von zwei Mengen gleich sind
Gl.

Antworten:

103

Sie können behaupten, dass die beiden Sets gleich sind, wodurch die Set equals()Methode aufgerufen wird .

public class SimpleTest {

    private Set<String> setA;
    private Set<String> setB;

    @Before
    public void setUp() {
        setA = new HashSet<String>();
        setA.add("Testing...");
        setB = new HashSet<String>();
        setB.add("Testing...");
    }

    @Test
    public void testEqualSets() {
        assertEquals( setA, setB );
    }
}

Dies @Testist erfolgreich, wenn die beiden Sets dieselbe Größe haben und dieselben Elemente enthalten.

Bill die Eidechse
quelle
7
Dies zeigt keine sehr guten Ergebnisse im Bericht an. Wenn Ihre toStrings klar definiert sind, ist es besser, aber immer noch nicht gut (Ein kleiner Unterschied kann zu einer Textseite führen)
Bill K
Ähm, wie kommt es, dass ich: java.lang.AssertionError: erwartet: java.util.Hashtable <{CompanyName = 8PKQ9va3nW8pRWb4SjPF2DvdQDBmlZ, Ric = sZwmXAdYKv, Category = AvrIfd, QuoteId> = 8PKQ9va3nW8pRWb4SjPF2DvdQDBmlZ, Ric = sZwmXAdYKv, Kategorie = AvrIfd, QuoteId = 4342740204922826921}>
Giovanni Botta
3
@Giodude Haben Sie, equalsund hashCodein der Klasse implementiert , dass Sie in Ihrem Hashtable sind speichern?
Bill the Lizard
Wie Sie sehen können, sind dies nur Zeichenfolgen und eine lange ... Ich teste Avro, um eine Karte zu serialisieren und zu de-serialisieren, und das ist das Ergebnis. Ich denke, es muss etwas faul sein mit der Art und Weise, wie die Zeichenfolgen serialisiert und de-serialisiert werden, was den Test zum Scheitern bringt, aber ich kann das Problem nicht finden.
Giovanni Botta
Hat bei mir nicht funktioniert, obwohl ich zwei HashSet <Long> vergleiche. @ MattFriedman Antwort funktioniert tatsächlich für meinen Anwendungsfall.
Bluecollarcoder
46

Apache kommt wieder zur Rettung.

assertTrue(CollectionUtils.isEqualCollection(coll1, coll2));

Klappt wunderbar. Ich weiß nicht warum, aber ich habe festgestellt, dass bei Sammlungen Folgendes assertEquals(coll1, coll2)nicht immer funktioniert. Für den Fall, dass es für mich fehlschlug, hatte ich zwei Sammlungen, die von Sets unterstützt wurden. Weder Hamcrest noch Junit würden sagen, dass die Sammlungen gleich waren, obwohl ich sicher wusste, dass sie es waren. Mit CollectionUtils funktioniert es perfekt.

Matt Friedman
quelle
20
Dies ist eigentlich trivial, der schwierige Teil ist es, den Unterschied zum Anrufer klar anzuzeigen
Bill K
1
Die akzeptierte Antwort ist eine gute Antwort auf die ursprüngliche Frage (Komponententest speziell für zwei Sätze), aber diese Antwort mit CollectionUtils ist meiner Meinung nach eine bessere Antwort für den allgemeinsten Fall. Ich konnte eine Sammlung und ein Set nur mit CollectionUtils vergleichen.
Jay
16

mit hamcrest :

assertThat(s1, is(s2));

mit klarer Behauptung:

assertEquals(s1, s2);

NB: t Die Methode equals () der konkreten Mengenklasse wird verwendet

dfa
quelle
1
Ich bevorzuge diese Methode, da Hamcrest mit JUnit 4 geliefert wird und daher keine weiteren Bibliotheken erforderlich sind.
JRSofty
2
Dies funktioniert möglicherweise nicht, wenn die Sets unterschiedliche Typen haben.
Hans-Peter Störr
7

Ein besonders interessanter Fall ist der Vergleich

   java.util.Arrays$ArrayList<[[name,value,type], [name1,value1,type1]]> 

und

   java.util.Collections$UnmodifiableCollection<[[name,value,type], [name1,value1,type1]]>

Bisher sehe ich nur die Lösung, beide in Sets umzuwandeln

assertEquals(new HashSet<CustomAttribute>(customAttributes), new HashSet<CustomAttribute>(result.getCustomAttributes()));

Oder ich könnte sie Element für Element vergleichen.


quelle
Tatsächlich gibt es dafür mehrere Lösungen, die in den anderen Antworten vorgestellt werden. Sets sind dafür sowieso etwas unglücklich, da sie die Reihenfolge ignorieren. Vielleicht ArrayList?
Hans-Peter Störr
4

Als zusätzliche Methode, die auf Arrays basiert, können Sie die Verwendung ungeordneter Array-Zusicherungen in junitx in Betracht ziehen. Obwohl das Beispiel Apache CollectionUtils funktioniert, gibt es dort auch eine Reihe solider Assertion-Erweiterungen:

ich glaube, dass der

ArrayAssert.assertEquivalenceArrays(new Integer[]{1,2,3}, new Integer[]{1,3,2});

Der Ansatz ist für Sie viel besser lesbar und debuggbar (alle Sammlungen unterstützen toArray (), daher sollte es einfach genug sein, die ArrayAssert-Methoden zu verwenden.

Der Nachteil hierbei ist natürlich, dass junitx eine zusätzliche JAR-Datei oder ein Maven-Eintrag ist ...

 <dependency org="junit-addons" name="junit-addons" rev="1.4"/>
jayunit100
quelle
2

Überprüfen Sie diesen Artikel . Ein Beispiel von dort:

@Test  
public void listEquality() {  
    List<Integer> expected = new ArrayList<Integer>();  
    expected.add(5);  

    List<Integer> actual = new ArrayList<Integer>();  
    actual.add(5);  

    assertEquals(expected, actual);  
}  
römisch
quelle
kurzer aber toller Link, erklärt sehr schnell, was man mit Junit4- machen kann
Johannes
1
Die Verbindung ist unterbrochen. Gibt es eine Chance, dass Sie eine archivierte Version online finden oder deren Inhalt zusammenfassen können?
pzp
1

Verwenden von Hamcrest:

assertThat( set1, both(everyItem(isIn(set2))).and(containsInAnyOrder(set1)));

Dies funktioniert auch, wenn die Sets unterschiedliche Datentypen haben und über den Unterschied berichten, anstatt nur zu versagen.

Hans-Peter Störr
quelle
2
Was ist der Import für isIn? IntelliJ kann den Import mit keinem hamcret-Paket auflösen.
Fabien
0

Wenn Sie überprüfen möchten, ob eine Liste oder ein Satz einen Satz bestimmter Werte enthält (anstatt ihn mit einer bereits vorhandenen Sammlung zu vergleichen), ist häufig die toString-Methode für Sammlungen hilfreich:

String[] actualResult = calltestedmethod();
assertEquals("[foo, bar]", Arrays.asList(actualResult).toString());

List otherResult = callothertestedmethod();
assertEquals("[42, mice]", otherResult.toString());

Dies ist etwas kürzer als das erste Erstellen der erwarteten Sammlung und der Vergleich mit der tatsächlichen Sammlung und einfacher zu schreiben und zu korrigieren.

(Zugegeben, dies ist keine besonders saubere Methode und kann ein Element "foo, bar" nicht von zwei Elementen "foo" und "bar" unterscheiden. In der Praxis halte ich es jedoch für das Wichtigste, dass es einfach und schnell ist, Tests zu schreiben , sonst werden viele Entwickler einfach nicht ohne Druck.)

Hans-Peter Störr
quelle
Dadurch hängt das Ergebnis Ihres Komponententests von der Implementierung von toString from list ab. Wenn sie die Formatierung ändern, funktioniert der Komponententest nicht mehr. Ich würde das nicht für sicher halten.
Laurens Op 't Zandt
@ LaurensOp'tZandt Du meinst, Oracle ändert das Format von Collection.toList ()? Das wird sicher nicht passieren. Sie haben jedoch Recht, das ist nicht besonders sauber. Aber in der Praxis ist mein Eindruck, dass es am wichtigsten ist, dass es sehr einfach ist, Tests zu schreiben.
Hans-Peter Störr
Ich stimme zu, ich denke, die toString-Methode wird wahrscheinlich kein Zufall sein. Also wird es wahrscheinlich weiter funktionieren. Ich wollte nur darauf hinweisen, dass es kein sehr sauberer Weg ist. Aber in der Tat ist es sehr einfach. Ein Problem, das auftritt, ist beim Vergleichen von Mengen. Da ihre Bestellung nicht garantiert ist.
Laurens Op 't Zandt
0

Ich mag die Lösung von Hans-Peter Störr ... Aber ich denke, es ist nicht ganz richtig. Leider containsInAnyOrdernicht Akzeptierte Collectionvon objetcs zu vergleichen. Also muss es ein Collectionvon Matchers sein:

assertThat(set1, containsInAnyOrder(set2.stream().map(IsEqual::equalTo).collect(toList())))

Die Importe sind:

import static java.util.stream.Collectors.toList;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.junit.Assert.assertThat;
FLUXpartikel
quelle