2017-03-10 18 views
7

製品を任意の順序で返品することができる場合は、どのように以下をリファクタリングしますか?リストの内容が順序付けられていない場合のAssertEquals

List<Product> products = get_products("test_produc"); 
assertEquals(products.size(),3); 
assertEquals(products.get(0).getName(), "test_product1"); 
assertEquals(products.get(1).getName(), "test_product2"); 
assertEquals(products.get(2).getName(), "test_produc3"); 

ストリームを使用してエレガントに行うことができれば、そのような提案にはうまくいきません。 Hamcrestの提案も大歓迎です。あなたはStream#anyMatch(Predicate filter)を使用してブール条件に主張することができます

+1

@ jpmc26これは私の意見では同じ質問ではありません。 – Baz

+0

これは何か?:assertThat(実際、containsInAnyOrder(expected.toArray())); – Morvader

+0

@Morvaderあなたの欠けているgetName() – Baz

答えて

7

注意してAbubakkarの答えを組み合わせると思います。これははるかに少ない入力と非常に明確なエラーメッセージを与えるでしょう。

戻り値に重複が含まれていない場合、リストの代わりにSetが返されます。

asssertEquals(Arrays.sort(Arrays.asList("Item1", "Item2")), Arrays.sort(get_products())); 

assertEquals(new HashSet<>(Arrays.asList("Item1", "Item2")), get_products()); 

を、これはあなたが両方の期待と実際の結果とそれらの比較を並べ替える必要があるオプションがない場合:あなたがテストしている機能を変更することができた場合は、次のようにあなたがそれをテストすることができ、この方法です

最後にあなたがHamcrestのマッチャ(機能containsInAnyOrderorg.hamcrest.collection.IsIterableContainingInAnyOrderである)を使用してに頼ることができます:私は、私たちに好むという状況で

assertThat(get_products(), containsInAnyOrder("Item1", "Item2")); 
2

このストリームのいずれかの要素が提供さ述語と一致するかどうかを返します。結果を決定するために必要でない場合、すべての要素の述語を評価しないことがあります。ストリームが空の場合は、falseが返され、述語は評価されません。

assertEquals(products.size(), 3); 
assertTrue(products.stream().anyMatch(p -> "test_product1".equals(p.getName()))); 
assertTrue(products.stream().anyMatch(p -> "test_product2".equals(p.getName()))); 
assertTrue(products.stream().anyMatch(p -> "test_product3".equals(p.getName()))); 
+0

しかし...なぜですか?私が知る限り、これはセットを使用する以上の利点はありません。それが重要であれば、多重度はまだ検出できません。これは線形(または線形)時間の代わりに二次時間を要します。はるかに冗長です。等 – wchargin

1

あなたは(私はそう単純に使用して、あなたがgetNameにのみ関心がある、と私はhamcrestを使用していないと仮定していますassertTruestreamを使用して、このような何かを試すことができます。

​​
+0

@downvoter、あなたは私の答えに間違いがあるとコメントしてください。 – Abubakkar

6

AssertJ -

import static org.assertj.core.api.Assertions.assertThat; 

// ...... 

List<String> products = get_products("test_produc").stream() 
    .map(Product::getName) 
    .collect(toList()); 

assertThat(products).containsExactlyInAnyOrder("Third", "Second", "First"); 

あなたはより多くの流暢なアサーション(特にthe exception handling ones)を提供します。

3

私はassertEqualsも直接リストとセットの上で動作することをHamcrest compare collections

List<String> productNames = products.stream() 
            .map(p -> p.getName()) 
            .collect(Collectors.toList()); 
// assert that the actual list does not contain additional elements: 
assertEquals(products.size(),3); 
assertThat(productNames, containsInAnyOrder("test_product1", "test_product2", "test_produc3")); 
+0

toListではない – Baz

1

をe assertJ。たぶんそれは満足できるでしょう。 例:

final List<String> actual = Arrays.asList("c", "b", "a"); 
    final List<String> expected = Arrays.asList("a", "b", "c"); 
    Assertions.assertThat(actual).containsOnlyElementsOf(expected); 
1

Hamcrestを知らない、私の解決策は、(それがそれらを変更するために許容できないかどうか、それらのコピー)各リストをソートして、それらが等しいと主張するだろう。

強度:リストに重複する商品がある場合にも機能します(別のリストに同じ重複が必要です)。

ストリームを使用して、製品リストから名前を抽出することができます。他の回答のいくつかはすでにどのように表示されています。

関連する問題