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)

Как я должен писать?

7 79

7 ответов:

если вы хотите утверждать, что два списка идентичны, не усложняйте ситуацию с Hamcrest:

assertEquals(expectedList, actual.getList());

если вы действительно намерены выполнить сравнение без учета заказа, вы можете вызвать containsInAnyOrder varargs метод и предоставить значения непосредственно:

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

(при условии, что ваш список String, а не Agent, например.)

если вы действительно хотите вызвать тот же метод с содержимым a List:

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

без этого вы вызываете метод с одним аргументом и создаете Matcher что ожидает матч с Iterable здесь в каждом элементе это List. Это не может быть использовано, чтобы соответствовать 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'S без избыточных параметров.

в дополнение к ответу @ Joe's:

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 (как В. 2.0.0.0) вы вынуждены использовать коллекция.метод toArray () в вашей коллекции для использования Containsinanyorder Matcher. Гораздо лучше было бы добавить это в качестве отдельного метода для орг.hamcrest.Вычислителей:

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());
}

на самом деле я закончил тем, что добавил Этот метод в свою пользовательскую тестовую библиотеку и использовал его для повышения читаемости моих тестовых случаев (из-за меньшей детализации).

для списка объектов, Вам может понадобиться что-то вроде этого:

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 если вы не хотите проверять порядок объектов.

P. S. В любой помощи, чтобы избежать предупреждения, suppresed буду очень признателен.

убедитесь, что Objects в вашем списке есть equals() определенными на них. Тогда

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

строительство.

чтобы сравнить два списка с сохраненным порядком использования,

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