JUnit 4のCollection
要素、特にSet
の等価性をどのように簡潔にアサートしますか?
2つのSet
sが互いに等しく、Set
equals()
method を呼び出すことをアサートできます。
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 );
}
}
この @Test
は、2つのSet
sが同じサイズで同じ要素を含む場合に合格します。
Apacheは再び救助に参加します。
_assertTrue(CollectionUtils.isEqualCollection(coll1, coll2));
_
魅力のように機能します。理由はわかりませんが、コレクションでは次のassertEquals(coll1, coll2)
が常に機能するとは限りません。私が失敗した場合、Setsによってバックアップされた2つのコレクションがありました。 hamcrestもjunitも、コレクションが同じであるとは確信していましたが、コレクションが等しいとは言いませんでした。 CollectionUtilsを使用すると、完全に機能します。
hamcrest :
assertThat(s1, is(s2));
明白なアサートで:
assertEquals(s1, s2);
NB:tconcrete set classのequals()メソッドが使用されます
特に興味深いケースは、比較するときです
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()));
または、要素ごとに比較することもできます。
配列ベースの追加メソッドとして... 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"/>
この記事 を確認してください。そこからの一例:
@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);
}
Hamcrestの使用:
assertThat( set1, both(everyItem(isIn(set2))).and(containsInAnyOrder(set1)));
これは、セットのデータ型が異なる場合にも機能し、単に失敗するのではなく、違いについて報告します。
リストまたはセットに特定の値のセットが含まれているかどうかを確認する場合(既存のコレクションと比較するのではなく)、コレクションのtoStringメソッドが便利です。
String[] actualResult = calltestedmethod();
assertEquals("[foo, bar]", Arrays.asList(actualResult).toString());
List otherResult = callothertestedmethod();
assertEquals("[42, mice]", otherResult.toString());
これは、予想されるコレクションを最初に構築し、実際のコレクションと比較するよりも少し短く、記述や修正が簡単です。
(確かに、これは特にクリーンなメソッドではなく、要素 "foo、bar"を2つの要素 "foo"および "bar"から区別することはできません。それ以外の場合、多くの開発者は押されずにはいられません。)
Hans-PeterStörrのソリューションが好きです...しかし、それはまったく正しくないと思います。悲しいことに、containsInAnyOrder
は、比較するobjetcのCollection
を受け入れません。したがって、Collection
sのMatcher
である必要があります。
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;