unidad toner recogida m553 laserjet ce254a java unit-testing testing junit

java - toner - ¿Mejor manera de probar la unidad de recogida?



unidad de recogida de toner hp laserjet m553 (4)

Me pregunto cómo la prueba unitaria de la gente y afirmar que la colección "esperada" es la misma / similar a la colección "real" (el orden no es importante).

Para realizar esta afirmación, escribí mi API de aserción simple:

public void assertCollection(Collection<?> expectedCollection, Collection<?> actualCollection) { assertNotNull(expectedCollection); assertNotNull(actualCollection); assertEquals(expectedCollection.size(), actualCollection.size()); assertTrue(expectedCollection.containsAll(actualCollection)); assertTrue(actualCollection.containsAll(expectedCollection)); }

Bueno, funciona. Es bastante simple si estoy afirmando solo un puñado de enteros o cadenas. También puede ser bastante doloroso si estoy tratando de afirmar una colección de dominios de Hibernate, por ejemplo. Collection.containsAll (..) confía en los iguales (..) para realizar el control, pero siempre anulo los iguales (..) en mis dominios de Hibernate para verificar solo las claves de negocios (que es la mejor práctica establecida en el Sitio web de Hibernate) y no todos los campos de ese dominio. Claro, tiene sentido verificar solo las claves de negocios, pero hay ocasiones en las que realmente quiero asegurarme de que todos los campos sean correctos, no solo las claves de negocios (por ejemplo, el nuevo registro de ingreso de datos). Entonces, en este caso, no puedo perder el dominio con domain.equals (..) y parece que necesito implementar algunos comparadores solo para pruebas de unidad en lugar de confiar en collection.containsAll (..).

¿Hay algunas bibliotecas de prueba que podría aprovechar aquí? ¿Cómo pruebas tu colección?

Gracias.


No estoy seguro de qué versión de JUnit está utilizando, pero las más recientes tienen un método assertThat que toma un Hamcrest Matcher como argumento. Se pueden componer para que pueda crear aserciones complejas sobre una colección.

Por ejemplo, si quisiera afirmar que una colección A contenía cada elemento de la colección B , podría escribir:

import static org.junit.Assert.*; import static org.junit.matchers.JUnitMatchers.*; import static org.hamcrest.core.IsCollectionContaining.*; import static org.hamcrest.collection.IsCollectionWithSize.*; import org.hamcrest.beans.SamePropertyValuesAs; public class CollectionTests { /* * Tests that a contains every element in b (using the equals() * method of each element) and that a has the same size as b. */ @Test public void test() { Collection<Foo> a = doSomething(); Collection<Foo> b = expectedAnswer; assertThat(a, both(hasItems(b)).and(hasSize(b.size()))); } /* * Tests that a contains every element in b (using introspection * to compare bean properties) and that a has the same size as b. */ @Test public void testBeans() { Collection<Foo> a = doSomething(); Collection<Foo> b = expectedAnswer; Collection<Matcher<Foo>> bBeanMatchers = new LinkedList<Matcher<Foo>>(); // create a matcher that checks for the property values of each Foo for(Foo foo: B) bBeanMatchers.add(new SamePropertyValuesAs(foo)); assertThat(a, both(hasItems(bBeanMatchers)).and(hasSize(b.size()))) } }

La primera prueba solo usa el emparejador equalTo () en cada objeto (que se delegará a su implementación de igual a igual). Si eso no es lo suficientemente fuerte, puedes usar el segundo caso, que usará los captadores y los configuradores para comparar cada elemento. Finalmente, incluso puedes escribir tus propios matchers. El paquete Hamcrest no viene con un emparejador para hacer coincidir por campo (en lugar de emparejar las propiedades del bean), pero es trivial escribir un FieldMatcher (y de hecho es un buen ejercicio).

Los Matchers son un poco raros al principio, pero si sigues su ejemplo de cómo hacer que los nuevos Matchers tengan un método estático que los devuelva, puedes hacer un montón de import static y tu código básicamente se lee como una oración en inglés ("afirma que ambos tienen los elementos en b y tienen el mismo tamaño que b "). Puede crear un DSL bastante impresionante con estas cosas y hacer que su código de prueba sea mucho más elegante.


No pude conseguir que la última parte de la respuesta de jasonmp85 funcionara como está. Incluí las importaciones que utilicé porque algunos tarros junit incluyen cosas viejas de hamcrest para mayor comodidad. Esto funciona para mí, pero el ciclo de hasItems(..) definitivamente no es tan bueno como si hasItems(..) funcionara como está escrito en la respuesta de hasItems(..) .

import org.hamcrest.Matcher; import org.hamcrest.beans.SamePropertyValuesAs; import org.hamcrest.collection.IsCollectionWithSize; import static org.hamcrest.CoreMatchers.hasItem; import static org.hamcrest.MatcherAssert.assertThat; ... /* * Tests that a contains every element in b (using introspection * to compare bean properties) and that a has the same size as b. */ @Test public void testBeans() { Collection<Foo> a = doSomething(); Collection<Foo> b = expectedAnswer; Collection<Matcher<Foo>> bBeanMatchers = new LinkedList<Matcher<Foo>>(); // create a matcher that checks for the property values of each Foo for(Foo foo: B) bBeanMatchers.add(new SamePropertyValuesAs(foo)); // check that each matcher matches something in the list for (Matcher<Foo> mf : bBeanMatchers) assertThat(a, hasItem(mf)); // check that list sizes match assertThat(a, IsCollectionWithSize.hasSize(b.size())); } ...


Otra opción si no has construido tu colección:

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

Utilice containsInAnyOrder si no desea verificar el orden de los objetos.

PD Cualquier ayuda para evitar la advertencia que se suprime será realmente apreciada.


Si el método equals no comprueba todos los campos, puede usar la clase http://unitils.org/ ReflectionAssert Unitils. Vocación

ReflectionAssert.assertReflectionEquals(expectedCollection,actualCollection)

comparará cada elemento reflexivamente campo por campo (y esto no solo se aplica a las colecciones, sino que también funcionará para cualquier objeto).