[java] Hamcrest 비교 컬렉션

두 목록을 비교하려고합니다.

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)

어떻게 작성해야합니까?



답변

두 목록이 동일하다고 주장하려면 Hamcrest를 사용하여 복잡하게 만들지 마십시오.

assertEquals(expectedList, actual.getList());

순서를 구분하지 않는 비교를 수행하려는 경우 containsInAnyOrdervarargs 메서드를 호출하고 값을 직접 제공 할 수 있습니다.

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

( 이 예에서는 목록 이이 String아니라 라고 가정합니다 Agent.)

a의 내용으로 동일한 메서드를 정말로 호출하려면 List:

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

이 없다면, 당신은 하나의 인수를 사용하여 메소드를 호출하고을 만들 Matcher예상하는가 일치하는 것을 Iterable어디에 각 요소가 입니다 List. .NET과 일치하는 데 사용할 수 없습니다 List.

즉, 당신은 일치하지 수 List<Agent>로모그래퍼 Matcher<Iterable<List<Agent>>코드를 시도하고 무엇이다.


답변

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

중복 매개 변수가없는 @Joe의 답변의 짧은 버전.


답변

@Joe의 대답을 보완하려면 다음을 수행하십시오.

Hamcrest는 목록을 일치시키는 세 가지 주요 방법을 제공합니다.

contains 순서를 세는 모든 요소가 일치하는지 확인합니다. 목록에 요소가 더 많거나 적 으면 실패합니다.

containsInAnyOrder 모든 요소와 일치하는지 확인하고 순서는 중요하지 않습니다. 목록에 요소가 더 많거나 적 으면 실패합니다.

hasItems 지정된 개체 만 확인합니다. 목록에 더 많은 항목이 있는지 여부는 중요하지 않습니다.

hasItem 하나의 개체 만 확인합니다. 목록에 더 많은 항목이 있는지 여부는 중요하지 않습니다.

그들 모두는 객체 목록을 수신하고 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 …)


답변

기존 Hamcrest 라이브러리 (v.2.0.0.0 기준)에서는 containsInAnyOrder Matcher를 사용하기 위해 Collection에서 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());
}

실제로이 메서드를 사용자 지정 테스트 라이브러리에 추가하고 테스트 사례의 가독성을 높이는 데 사용했습니다 (더 적은 자세한 정보로 인해).


답변

Object목록 의 s가 equals()정의되어 있는지 확인하십시오 . 그때

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

공장.


답변

객체 목록의 경우 다음과 같은 것이 필요할 수 있습니다.

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를 사용하십시오 .

추신 : 예상되는 경고를 피하는 데 도움을 주시면 정말 감사하겠습니다.


답변

두 목록을 순서 보존 사용과 비교하려면

assertThat(actualList, contains("item1","item2"));