55

hamcrest を使用して、2 つのマップが等しい、つまり、同じ値を指す同じキー セットを持っていることを主張したいと思います。

私の現在の最良の推測は次のとおりです。

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

与える:

assertThat(T, Matcher<T>)型のメソッドAssertは引数に適用できません ( Set<Map.Entry<Householdtypes,Double>>, Matcher<Iterable<Set<Map.Entry<Householdtypes,Double>>>>)

のバリエーションcontainsAll、および hamcrest パッケージによって提供される他のいくつかも調べました。誰かが私を正しい方向に向けることができますか? または、カスタムマッチャーを作成する必要がありますか?

4

9 に答える 9

59

私が思いついた最短の方法は、2 つのステートメントです。

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

しかし、おそらく次のこともできます。

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

マップの実装に依存し、差分レポートの明確さを犠牲にします。それは違いがあることを伝えるだけですが、上記のステートメントはどれがどれかを教えてくれます.

更新: 実際には、コレクションの種類とは無関係に機能するステートメントが 1 つあります。

assertThat(affA.entrySet(), both(everyItem(isIn(affB.entrySet()))).and(containsInAnyOrder(affB.entrySet())));
于 2012-08-27T15:45:10.317 に答える
40

時にはMap.equals()十分です。しかし、Mapテスト中のコードによって返される s の型がわからない場合.equals()があるため、コードによって返される未知の型のマップと作成したマップを適切に比較できるかどうかわかりません。または、コードをそのようなテストにバインドしたくない場合。

さらに、結果を比較するためにマップを個別に構築することは、私見ではあまりエレガントではありません。

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));

私はマッチャーを使用することを好みます:

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))
));

私は自分自身を定義する必要がありますhasSize()

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");
        }
    };
}

またhasEntry()、キーと値の正確な値の代わりに、マッチャーをパラメーターとして受け取る別のバリ​​アントがあります。これは、すべてのキーと値の等価性テスト以外の何かが必要な場合に役立ちます。

于 2011-11-19T19:50:07.477 に答える
2

現在利用可能な別のオプションは、HamcrestのCirneco 拡張機能を使用することです。それはhasSameKeySet()(Guava「コレクション」の他のマッチャーと同様に)持っています。あなたの例によれば、それは次のようになります。

assertThat(affA, hasSameKeySet(affB));

JDK7 ベースのプロジェクトには、次の依存関係を使用できます。

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

JDK8 以上を使用している場合は、次のようになります。

<dependency>
  <groupId>it.ozimov</groupId>
  <artifactId>java8-hamcrest-matchers</artifactId>
  <version>0.7.0</version>
</dependency>
于 2015-12-30T14:17:57.140 に答える
0

Hamcrest にMatcherfor size コレクションが追加されました。

org.hamcrest.collection.IsCollectionWithSize

于 2016-09-10T06:51:39.637 に答える