web-dev-qa-db-ja.com

Hamcrest比較コレクション

私は2つのリストを比較しようとしています:

assertThat(actual.getList(), is(Matchers.containsInAnyOrder(expectedList)));

しかし、考え

Java: no suitable method found for assertThat(Java.util.List<Agent>,org.hamcrest.Matcher<Java.lang.Iterable<? extends model.Agents>>)
method org.junit.Assert.<T>assertThat(T,org.hamcrest.Matcher<T>) is not applicable
  (no instance(s) of type variable(s) T exist so that argument type org.hamcrest.Matcher<Java.lang.Iterable<? extends model.Agents>> conforms to formal parameter type org.hamcrest.Matcher<T>)
method org.junit.Assert.<T>assertThat(Java.lang.String,T,org.hamcrest.Matcher<T>) is not applicable
  (cannot instantiate from arguments because actual and formal argument lists differ in length)

どのように書くべきですか?

92
xander27

2つのリストが同一であると断言したい場合は、Hamcrestを複雑にしないでください。

assertEquals(expectedList, actual.getList());

順序に依存しない比較を本当に実行する場合は、containsInAnyOrdervarargsメソッドを呼び出して、値を直接指定できます。

assertThat(actual.getList(), containsInAnyOrder("item1", "item2"));

(この例では、リストがStringname__ではなく、Agentname__であると想定しています。)

Listname__の内容で同じメソッドを本当に呼び出したい場合:

assertThat(actual.getList(), containsInAnyOrder(expectedList.toArray(new String[expectedList.size()]));

これがない場合、単一の引数でメソッドを呼び出し、Matchername__に一致することを期待するIterablename__を作成します。ここで、各要素Listname__です。これは、Listname__との一致には使用できません。

つまり、List<Agent>Matcher<Iterable<List<Agent>>を一致させることはできません。これは、コードが試行していることです。

138
Joe
List<Long> actual = Arrays.asList(1L, 2L);
List<Long> expected = Arrays.asList(2L, 1L);
assertThat(actual, containsInAnyOrder(expected.toArray()));

冗長パラメーターのない@Joeの回答の短いバージョン。

51
Jofsey

@Joeの答えを補完するには:

Hamcrestは、リストを照合するための3つの主な方法を提供します。

containsは、順序をカウントするすべての要素と一致するかどうかをチェックします。リストに含まれる要素が多かったり少なかったりすると、失敗します

containsInAnyOrderすべての要素が一致するかどうかをチェックします。順序に関係なく、リストに含まれる要素が多かったり少なかったりすると、失敗します

hasItems指定されたオブジェクトのみをチェックし、リストにもっとあるかどうかは関係ありません

hasItem 1つのオブジェクトだけをチェックし、リストにさらにオブジェクトがあるかどうかは関係ありません

それらはすべてオブジェクトのリストを受け取り、比較のためにequalsメソッドを使用するか、@ borjabのような他のマッチャーと混合できます:

assertThat(myList , contains(allOf(hasProperty("id", is(7L)), 
                                   hasProperty("name", is("testName1")),
                                   hasProperty("description", is("testDesc1"))),
                             allOf(hasProperty("id", is(11L)), 
                                   hasProperty("name", is("testName2")),
                                   hasProperty("description", is("testDesc2")))));

http://hamcrest.org/JavaHamcrest/javadoc/1.3/org/hamcrest/Matchers.html#contains(E ...)http://hamcrest.org/JavaHamcrest/ javadoc/1.3/org/hamcrest/Matchers.html#containsInAnyOrder(Java.util.Collection)http://hamcrest.org/JavaHamcrest/javadoc/1.3/org/hamcrest/Matchers.html#hasItems (T ...)

17
rvazquezglez

既存のHamcrestライブラリ(v.2.0.0.0以降)では、containsInAnyOrder Matcherを使用するために、コレクションでCollection.toArray()メソッドを使用する必要があります。 org.hamcrest.Matchersに別のメソッドとしてこれを追加する方がはるかに良いでしょう:

public static <T> org.hamcrest.Matcher<Java.lang.Iterable<? extends T>> containsInAnyOrder(Collection<T> items) {
    return org.hamcrest.collection.IsIterableContainingInAnyOrder.<T>containsInAnyOrder((T[]) items.toArray());
}

実際、私はこのメソッドをカスタムテストライブラリに追加し、それを使用してテストケースの読みやすさを向上させました(冗長性が低いため)。

9
yvolk

リスト内のObjectsにequals()が定義されていることを確認してください。それから

    assertThat(generatedList,is(equalTo(expectedList)));

動作します。

2
Jim Jarrett

オブジェクトのリストには、次のようなものが必要になる場合があります。

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.beans.HasPropertyWithValue.hasProperty;
import static org.hamcrest.Matchers.is;

@Test
@SuppressWarnings("unchecked")
public void test_returnsList(){

    arrange();

    List<MyBean> myList = act();

    assertThat(myList , contains(allOf(hasProperty("id",          is(7L)), 
                                       hasProperty("name",        is("testName1")),
                                       hasProperty("description", is("testDesc1"))),
                                 allOf(hasProperty("id",          is(11L)), 
                                       hasProperty("name",        is("testName2")),
                                       hasProperty("description", is("testDesc2")))));
}

オブジェクトの順序を確認したくない場合は、 containsInAnyOrder を使用します。

追伸抑制される警告を回避するための助けは本当にありがたいです。

1
borjab