web-dev-qa-db-ja.com

リストの内容が順序付けされていない場合の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");

ストリームを使用してエレガントに実行できるのであれば、私はそのような提案を受け入れません。ハムクレストの提案も歓迎します。

9
Baz

assertEqualsはリストとセットでも直接機能することに注意してください。これは入力がはるかに少なく、非常に明確なエラーメッセージが表示されます。

戻り値に重複を含めることが許可されていない場合は、リストではなくセットを返す必要があります。テストしている機能を変更できる場合は、次のようにテストできます。

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

これがオプションでない場合は、期待される結果と実際の結果の両方を並べ替えて、それらを比較する必要があります。

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

最後に、Hamcrestマッチャーの使用に頼ることができます(関数containsInAnyOrderorg.hamcrest.collection.IsIterableContainingInAnyOrderにあります):

assertThat(get_products(), containsInAnyOrder("Item1", "Item2"));
7
Thirler

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

さらに、より多くの流暢なアサーション(特に 例外処理のもの )も提供します。

7
MD Sayem Ahmed

Abubakkarの答えを Hamcrest比較コレクション と組み合わせる

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"));
3
sruetti

Stream#anyMatch(Predicate filter) :を使用して、ブール条件でアサートできます。

このストリームのいずれかの要素が指定された述語と一致するかどうかを返します。結果を決定するために必要でない場合、すべての要素の述語を評価しない場合があります。ストリームが空の場合、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())));
2
manouti

Hamcrestを知らないので、私の解決策は、各リスト(または、それらを変更することが許容されない場合はそれらのコピー)を並べ替えてから、それらが等しいと主張することです。

強み:リストに重複する製品がある場合にも機能します(他のリストにも同じ重複が必要になります)。

ストリームを使用して、製品リストから名前を抽出できます。他の回答のいくつかはすでにその方法を示しています。

1
Ole V.V.

そのような状況では、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
K. Gol

streamを使用してこのようなことを試すことができます(あなたはgetNameにのみ興味があり、ハムクレストを使用したことがないので、単純なassertTrueを使用します):

List<String> productNames = products.stream()
                                    .map(p -> p.getName())
                                    .collect(Collectors.toList());

assertTrue(productNames.contains("test_product1"));
assertTrue(productNames.contains("test_product2"));
assertTrue(productNames.contains("test_product3"));
1
Abubakkar