junit - matchers - Cómo utilizar Hamcrest para inspeccionar elementos del mapa
org hamcrest matchers api (3)
Así que para hacer esto más simple, puedes intentar esto ...
assertThat((Object)map, (Matcher)Matchers.hasEntry("one", hasItem(hasProperty("name", is("One")))));
al ingresar a un tipo sin formato, recibirá una advertencia pero no un error de compilación. Si he usado este truco en el pasado cuando no quiero preocuparme por tener todo el casting correcto para el compilador.
Además, puede considerar usar ItIterableContainingInOrder.containingInOrder(new MyItem("One")))
. Esto verificará la lista completa y si MyItem
implementa equals
entonces no MyItem
reflexión en tus pruebas.
Recientemente he estado usando la biblioteca de Hamcrest para escribir algunas pruebas y he tenido bastante éxito, pero ahora necesito hacer algo más complejo y empecé a ver muchas dificultades. Necesito inspeccionar y verificar las propiedades de los elementos en un mapa. Mi código de producción es algo así:
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")));
Quiero escribir algunos códigos de prueba como los siguientes, pero no se compila. Parece que hasEntry de Hamcrest tiene parámetros de tipo, mientras que hasItem y hasProperty solo esperan Object.
assertThat(map, Matchers.<String, List<MyItem>>hasEntry("one", hasItem(hasProperty("name", is("One")))));
My IDE (Eclipse) da este mensaje de error: el método parametrizado <String, List<HamcrestTest.MyItem>>hasEntry(String, List<HamcrestTest.MyItem>)
de tipo Matchers
no es aplicable para los argumentos (String, Matcher<Iterable<? super Object>>)
. Por un lado, creo que Eclipse está confundido sobre qué método hasEntry
quería usar, debería ser hasEntry(org.hamcrest.Matcher<? super K> keyMatcher, org.hamcrest.Matcher<? super V> valueMatcher)
, no hasEntry(K key, V value)
.
¿Debo rendirme y obtener el elemento del mapa e inspeccionar manualmente cada propiedad? ¿Hay alguna forma más limpia?
Usted podría simplemente utilizar contains
o containsInAnyOrder
. Es cierto que tendrá que enumerar todos los elementos en la List
esa manera, pero funciona más limpio que 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")))));
}
Ya que @ t0mppa no proporcionó un buen ejemplo sobre cómo usar Hamcrest contains
y containsInAnyOrder
InAnyOrder para esto, aquí hay algo para comenzar:
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
Tenga en cuenta que, a diferencia de hasItem
y hasItems
, solo funcionarán si les proporciona una lista completa de todos los valores con los que se comparará. Ver javadocs de javadocs para más información.