Frage

Ich möchte hamcrest zu behaupten verwenden, die zwei Karten gleich sind, das heißt, sie den gleichen Satz von Tasten zeigen auf die gleichen Werte.

Meine aktuelle beste Vermutung ist:

assertThat( affA.entrySet(), hasItems( affB.entrySet() );

das gibt:

  

Das Verfahren assertThat (T, Matcher) in der Art Assert ist nicht anwendbar für die Argumente (Set>, Matcher >>>)

Ich habe auch in Variationen von containsAll sah, und einige andere von den hamcrest Pakete zur Verfügung gestellt. Kann jemand Punkt mich in die richtige Richtung? Oder muß ich einen benutzerdefinierten Matcher schreiben?

War es hilfreich?

Lösung

Der kürzeste Weg, ich habe kommen mit zwei Aussagen:

assertThat( affA.entrySet(), everyItem(isIn(affB.entrySet())));
assertThat( affB.entrySet(), everyItem(isIn(affA.entrySet())));

Sie können aber wahrscheinlich auch tun:

assertThat(affA.entrySet(), equalTo(affB.entrySet()));

in Abhängigkeit von den Implementierungen der Karten.

UPDATE: tatsächlich gibt es eine Anweisung, die unabhängig von den Sammlungstypen arbeitet:

assertThat(affA.entrySet, both(everyItem(isIn(affB.entrySet()))).and(containsInAnyOrder(affB.entrySet())));

Andere Tipps

Manchmal ist Map.equals() genug. Aber manchmal wissen Sie nicht die Typen von Maps von Code unter Tests zurückgeführt werden, so dass Sie nicht wissen, ob .equals() wird es dann richtig Karte unbekannter Art von Code mit der Karte von Ihnen konstruiert zurück vergleichen. Oder Sie möchten nicht Ihren Code mit solchen Tests binden.

Zusätzlich separat eine Karte Konstruktion damit das Ergebnis zu vergleichen ist IMHO nicht sehr elegant:

Map<MyKey, MyValue> actual = methodUnderTest();

Map<MyKey, MyValue> expected = new HashMap<MyKey, MyValue>();
expected.put(new MyKey(1), new MyValue(10));
expected.put(new MyKey(2), new MyValue(20));
expected.put(new MyKey(3), new MyValue(30));
assertThat(actual, equalTo(expected));

Ich ziehe mit Macher:

import static org.hamcrest.Matchers.hasEntry;

Map<MyKey, MyValue> actual = methodUnderTest();
assertThat(actual, allOf(
                      hasSize(3), // make sure there are no extra key/value pairs in map
                      hasEntry(new MyKey(1), new MyValue(10)),
                      hasEntry(new MyKey(2), new MyValue(20)),
                      hasEntry(new MyKey(3), new MyValue(30))
));

Ich habe hasSize() selbst zu definieren:

public static <K, V> Matcher<Map<K, V>> hasSize(final int size) {
    return new TypeSafeMatcher<Map<K, V>>() {
        @Override
        public boolean matchesSafely(Map<K, V> kvMap) {
            return kvMap.size() == size;
        }

        @Override
        public void describeTo(Description description) {
            description.appendText(" has ").appendValue(size).appendText(" key/value pairs");
        }
    };
}

Und es gibt eine weitere Variante von hasEntry() die Matcher als Parameter anstelle von exakten Werten von Schlüssel und Wert annimmt. Dies kann für den Fall nützlich sein, müssen Sie etwas anderes als Gleichheit Prüfung jedes einzelnen Schlüssel und Wert.

Ich bin dafür mit Guava ImmutableMap . Sie unterstützen Map.equals() und sind leicht zu konstruieren. Der einzige Trick besteht darin, explizit Typ Parameter angeben, da hamcrest den ImmutableMap Typen nehmen.

assertThat( actualValue,
            Matchers.<Map<String, String>>equalTo( ImmutableMap.of(
                "key1", "value",
                "key2", "other-value"
) ) );

Eine weitere Option ist jetzt die Cirneco Erweiterung für hamcrest zu verwenden. Es hat hasSameKeySet() (sowie andere Matcher für Guava „Sammlungen“). Nach Ihrem Beispiel wird es sein:

assertThat(affA, hasSameKeySet(affB));

Sie können die folgende Abhängigkeit für eine Verwendung JDK7-basiertes Projekt:

<dependency>
  <groupId>it.ozimov</groupId>
  <artifactId>java7-hamcrest-matchers</artifactId>
  <version>0.7.0</version>
</dependency>

oder nach dem, wenn Sie mit JDK8 oder überlegen:

<dependency>
  <groupId>it.ozimov</groupId>
  <artifactId>java8-hamcrest-matchers</artifactId>
  <version>0.7.0</version>
</dependency>

Eine ganz einfache Art und Weise ist eine Dienstprogramm Methode von Guava der com.google.common.collect.Maps Klasse zu verwenden.

assertThat(Maps.difference(map1,map2).areEqual(),is(true));

hamcrest hat jetzt eine Matcher für Größe Sammlung.

org.hamcrest.collection.IsCollectionWithSize

Das funktioniert wie ein Charme und erfordert keine zwei Behauptungen wie die akzeptierte Antwort.

assertThat( actualData.entrySet().toArray(), 
    arrayContainingInAnyOrder(expectedData.entrySet().toArray()) );

Wenn Sie eine Reihe von Ergebnissen mit Erwartungen vergleichen und wenn Sie assertj Bibliothek, können Sie dies tun:

// put set of expected values by your test keys
Map<K, V> expectations = ...;

// for each test key get result
Map<K, V> results = expectations.keySet().stream().collect(toMap(k -> k, k -> getYourProductionResult(k)));

assertThat(results).containsAllEntriesOf(expectations);

Beachten Sie, dass containsAllEntriesOf nicht zu vergleichen Karten für die Gleichstellung. Wenn Ihre Produktion Code tatsächlich eine Map<K, V> zurückgibt können Sie einen Scheck für Schlüssel hinzuzufügen assertThat(results).containsOnlyKeys((K[]) expectations.keySet().toArray());

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top