Как использовать Hamcrest для проверки элементов карты
недавно я использовал библиотеку Hamcrest для написания некоторых тестов и довольно успешно, но теперь мне нужно сделать что-то более сложное и начал видеть много трудностей. Мне нужно inpsect и проверить свойства элементов на карте. Мой производственный код выглядит примерно так:
Map<String, List<MyItem>> map = new HashMap<String, List<MyItem>>();
map.put("one", Arrays.asList(new MyItem("One")));
map.put("two", Arrays.asList(new MyItem("Two")));
map.put("three", Arrays.asList(new MyItem("Three")));
Я хочу написать некоторые тестовые коды, как показано ниже, но он не компилируется. Похоже, hasEntry Hamcrest тип-программируемых, а hasItem и метода ожидать только Объект.
assertThat(map, Matchers.<String, List<MyItem>>hasEntry("one", hasItem(hasProperty("name", is("One")))));
моя IDE (Eclipse) дает это сообщение об ошибке: параметризованный метод <String, List<HamcrestTest.MyItem>>hasEntry(String, List<HamcrestTest.MyItem>)
типа Matchers
- это не применимо для Аргументов (String, Matcher<Iterable<? super Object>>)
. Во-первых, я думаю, что Eclipse путают, из которых hasEntry
метод, который я хотел использовать, он должен быть!--6--> , а не hasEntry(K key, V value)
.
должен ли я просто сдаться и получить элемент с карты и вручную проверить каждое свойство? Есть ли более рациональный способ?
3 ответов
Youu может просто использовать contains
или containsInAnyOrder
. Правда, вам придется перечислить все элементы List
таким образом, но он работает чище, чем hasItem
:
@SuppressWarnings("unchecked")
@Test
public void mapTest() {
Map<String, List<MyItem>> map = new HashMap<String, List<MyItem>>();
map.put("one", asList(new MyItem("1"), new MyItem("one")));
assertThat(map, hasEntry(is("one"),
containsInAnyOrder(hasProperty("name", is("one")),
hasProperty("name", is("1")))));
}
поэтому, чтобы сделать это проще, вы можете попробовать это...
assertThat((Object)map, (Matcher)Matchers.hasEntry("one", hasItem(hasProperty("name", is("One")))));
перейдя к необработанному типу, вы получите предупреждение, но без ошибки компиляции. Если я использовал этот трюк в прошлом, когда я не хочу беспокоиться о том, чтобы получить все кастинг для компилятора.
кроме того, вы можете рассмотреть возможность использования ItIterableContainingInOrder.containingInOrder(new MyItem("One")))
. Это проверит весь список, и если MyItem
осуществляет equals
тогда вы не будете использовать отражение в своих тестах.
С @t0mppa не предоставила хороший пример о том, как использовать Hamcrest-х contains
и containsInAnyOrder
для этого, вот немного что-то, чтобы начать работу:
Map<Integer, String> columns = new HashMap<Integer, String>();
columns.put(1, "ID");
columns.put(2, "Title");
columns.put(3, "Description");
assertThat(columns.values(), contains("ID", "Title", "Description")); // passes
assertThat(columns.values(), contains("ID", "Description", "Title")); // fails
assertThat(columns.values(), containsInAnyOrder("ID", "Description", "Title")); // passes
обратите внимание, что в отличие от hasItem
и hasItems
, они будут работать только в том случае, если вы предоставите им полный список всех значений, с которыми вы будете сопоставлять. Увидеть Hamcrest-х javadocs для получения дополнительной информации.