JUnit 4比較セット


102

Collection要素の等価性、具体的にSetはJUnit 4のa をどのように簡潔に主張しますか?



2つのセットが互いに等しい(同じ要素を含む)、または同じセットの2つの要素が等しいと主張しようとしていますか?
トカゲに請求

2つのセットの要素が等しいことを確認する必要があります
Eqbal

回答:


103

2つSetのが互いに等しいことをアサートすると、Set equals()メソッドが呼び出されます。

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

@Test2つSetのが同じサイズで、同じ要素を含む場合、これは成功します。


7
これは、レポートに非常に良い結果を表示しません。toStringsが明確に定義されている場合、それは優れていますが、それでも不十分です(小さな違いがテキストのページで終わる可能性があります)
Bill K

ええと、どうやって取得するのですか。 = 8PKQ9va3nW8pRWb4SjPF2DvdQDBmlZ、Ric = sZwmXAdYKv、Category = AvrIfd、QuoteId = 4342740204922826921}>
Giovanni Botta

3
@Giodude Doが、あなたはしているequalshashCode、あなたのHashtableに保存していることをクラスで実装されましたか?
トカゲに請求する

ご覧のとおり、これらは単なる文字列と長いものです...私はAvroをテストして、マップをシリアル化およびシリアル化解除します。これが結果です。文字列のシリアル化とシリアル化解除の方法で、テストが失敗する原因となる魚がいると思いますが、問題を見つけることができないようです。
Giovanni Botta 2013年

2つのHashSet <Long>を比較していますが、うまくいきませんでした。@MattFriedmanの回答は、実際には私のユースケースで機能します。
bluecollarcoder 2014年

46

アパッチコモンズが再び救助に。

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

魅力のように機能します。なぜなのかはわかりませんが、コレクションでは次のassertEquals(coll1, coll2)ことが常に機能するとは限りません。私にとって失敗した場合、私はセットに支えられた2つのコレクションを持っていました。hamcrestもjunitも、コレクションが等しいと確信していたとしても、コレクションが等しいとは言いません。CollectionUtilsを使用すると、完全に機能します。


20
これは実際には取るに足らないことです。トリッキーな部分は、発信者に違いを明確に示すことです
Bill K

1
受け入れられた回答は、元の質問(特に2つのセットの単体テスト)に対する良い回答ですが、CollectionUtilsを使用したこの回答は、最も一般的なケースに適した回答だと思います。CollectionUtilsを使用しない限り、コレクションとセットを比較することはできませんでした。
ジェイ

16

hamcrest

assertThat(s1, is(s2));

明白な主張で:

assertEquals(s1, s2);

注意:具象セットクラスのequals()メソッドが使用されます


1
HamcrestにはJUnit 4が付属しているため、他のライブラリーを必要としないため、この方法を使用します。
JRSofty 2016年

2
セットのタイプが異なる場合、これは機能しない可能性があります。
Hans-PeterStörr2017年

7

特に興味深いケースは、

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

そして

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

これまでのところ、私が見る唯一の解決策は、両方をセットに変更することです

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

または、要素ごとに比較することもできます。


実際には、他の回答で提示されている解決策がいくつかあります。いずれにしても、セットは順序を無視するため、これは少し残念です。たぶん、ArrayList?
Hans-PeterStörr2017年

4

配列ベースの追加の方法として、junitxで順序なし配列アサーションを使用することを検討できます。Apache CollectionUtilsの例は機能しますが、そこにも固体アサーション拡張機能のパッケージがあります。

と思う

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

アプローチははるかに読みやすく、デバッグ可能です(すべてのコレクションがtoArray()をサポートしているため、ArrayAssertメソッドを使用するのは簡単です。

もちろん、ここでの欠点は、junitxが追加のjarファイルまたはmavenエントリであることです...

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

2

この記事を確認してください。そこからの一例:

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

短いが素晴らしいのリンクは、あなたがJunit4-で何ができるか本当に速い説明
ヨハネス

1
リンクが壊れています。アーカイブされたバージョンをオンラインで見つけたり、その内容を要約したりできますか?
pzp 2017年

1

Hamcrestの使用:

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

これは、セットのデータ型が異なる場合にも機能し、単に失敗するのではなく、その違いについて報告します。


2
isInのインポートは何ですか?IntelliJは、hamcretパッケージではインポートを解決できません。
fabien

0

(既存のコレクションと比較するのではなく)リストまたはセットに特定の値のセットが含まれているかどうかを確認する場合は、コレクションのtoStringメソッドが便利です。

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

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

これは、最初に予想されるコレクションを作成して実際のコレクションと比較するよりも少し短く、記述および修正が簡単です。

(確かに、これは特にクリーンな方法ではなく、要素「foo、bar」を2つの要素「foo」と「bar」から区別することはできません。しかし、実際には、テストを書くのが簡単で高速であることが最も重要だと思います、そうでなければ、多くの開発者は押されることなくしてはなりません。)


これにより、ユニットテストの結果は、リストからのtoStringの実装に依存します。彼らがフォーマットを変更することを決定した場合、ユニットテストはもはや機能しません。これは安全だとは思いません。
Laurens Op 't Zandt 2017年

@ LaurensOp'tZandt OracleがCollection.toList()のフォーマットを変更するということですか?それは確かに起こりません。しかし、あなたは特にきれいではありません。しかし実際には、テストを書くのは非常に簡単であることが最も重要であるという私の印象です。
Hans-PeterStörr2017年

私は同意します、toStringメソッドはおそらくチャンスではないと思います。したがって、おそらく機能し続けます。私はそれがあまりクリーンな方法ではないことを指摘したかっただけです。しかし、確かにそれはとても簡単です。セットを比較するときに発生する1つの問題です。それらの順序は保証されていないため。
Laurens Op 't Zandt

0

Hans-PeterStörrの解が好きです...しかし、私はそれがまったく正しくないと思います。悲しいcontainsInAnyOrderことに、Collection比較対象のオブジェクトを受け入れません。だからそれはCollectionMatchers でなければなりません:

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

インポートは次のとおりです。

import static java.util.stream.Collectors.toList;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.junit.Assert.assertThat;
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.