2012-04-12 25 views
30

¿Cómo se burlan las numerosas dependencias necesarias para las pruebas de integración?Burlarse de las pruebas de integración

Uso Mockito para mis pruebas de unidad "pura". 'Pure' en este caso significa probar una sola clase, burlarse de todas sus dependencias. Hermosa.

Ahora vienen las pruebas de integración. Digamos que en este caso, una prueba de integración será probar algo como esto:

  1. mensaje se coloca en una cola
  2. mensaje es 'procesada'
  3. mensaje de respuesta se pone en una cola de respuesta

Digamos también que el procesamiento que ocurre en el paso 2 es algo serio. Se basa en muchas interacciones de bases de datos, en múltiples servicios externos, el sistema de archivos, todo tipo de cosas. También hay muchos efectos secundarios que provocarán el flujo, por lo que no puedo simplemente asegurarme de que la respuesta sea correcta, necesito verificar los efectos secundarios.

Cada una de estas dependencias está envuelta por una sola clase de servicio sin estado, lo que las hace agradables y burlables.

¿Cómo lo están manejando?

Me encantaría usar Mockito para poder verificar los efectos secundarios que tendrá el flujo anterior. Sin embargo, la documentación de Mocktio (y en gran medida su implementación) parece luchar enérgicamente contra su uso en contextos distintos a las pruebas unitarias "puras". He tratado de seguir este camino, pero

  • Es difícil llenar los datos del trozo (ya que hay mucha de ella)
  • Es difícil tener Primavera inyectar esos casos tropezados en mis habas
  • Es difícil para 'reiniciar' los simulacros para que pueda verificar un conjunto diferente de interacciones sin borrar los talones.

EDITAR

Yo sé que podría manejar el tema de la base de datos con algo así como una instancia HSQLDB, pero aún existe la cuestión de los servicios externos. Para la repetibilidad no puedo confiar en que esos servicios estén funcionando, estar en el estado que requiero, etc. La única opción que veo es burlarse de ellos.

Whatdaya do?

+1

Solo para aclarar, ya que las pruebas de integración se pueden tomar de dos maneras. Parece que te refieres a las pruebas de integración, prueba que los componentes de conexión funcionan bien juntos (esencialmente probando las API). Pero, a veces la integración se refiere a un extremo a otro, por lo que no se burlaría de su servicio y realmente le permitiría llegar a la base de datos. Esta aclaración puede ayudar con la respuesta. Consulte http://stackoverflow.com/questions/4904096/whats-the-difference-between-unit-functional-acceptance-and-integration-test para obtener una mayor aclaración de los tipos –

+0

. realmente se aplica a cualquier prueba (integración o extremo a extremo) que requiera muchas dependencias externas. Por ejemplo, podría reemplazar mis apéndices de base de datos con una instancia de HSQLDB, pero todavía tengo todos los otros servicios. Editaremos la pregunta un poco para aclararlo ... –

+0

Entonces, ¿cómo resolvió el problema de la burla eventualmente? – Pupsik

Respuesta

7

Gran pregunta.

Parece que alcanzas los límites de Mockito. Mockito es genial si lo que quieres es inspeccionar las interacciones entre objetos.

Lo que quiere, sin embargo, parece ser observabilidad (y capacidad de control) en un nivel más alto de abstracción. Me temo que los simulacros o trozos que necesita para eso deben ser cuidadosamente diseñados y hechos a mano.

A nivel de la unidad, estos simulacros se pueden generar muy bien, mediante Mockito. En el nivel de integración, esto se vuelve mucho más difícil, y necesitará interfaces de comprobación de objetivos específicos.

+1

Sí, parece que a nivel de integración las personas "hacen lo mejor posible", ya sea haciendo lo que pueden con burlas en las bibliotecas o accediendo a instancias de prueba de servicios/bases de datos.Actualmente estoy trabajando en una extensión de Mockito basada en Groovy para ayudar a que las pruebas de integración sean un poco menos dolorosas. –

7

Para burlarse de cosas como bases de datos, servicios web, el sistema de archivos, etc., es probable que desee refactorizar un poco. Para cada servicio externo, debe escribir una clase contenedora que tenga un método para cada operación que desee realizar. Cada uno de estos métodos no debería tener una lógica real, sino simplemente pasar sus parámetros en la forma en que el servicio externo lo comprenderá, y devolver un objeto que contenga los datos que devuelva el servicio externo. Por ejemplo, si está interactuando con una base de datos, la clase contenedora podría formatear sus parámetros en una instrucción SQL, enviarlos a un objeto existente Connection y devolver un List para el resultado.

Porque los métodos de la clase contenedora no contienen lógica (es decir, no if/else, no loops y ningún manejo de excepciones); no hay necesidad de probar la unidad de la clase contenedora.Debería probar la integración de la clase contenedora, para asegurarse de que sus responsabilidades se realizan correctamente (es decir, que la declaración SQL tenga el efecto deseado en la base de datos, por ejemplo).

Ahora vuelve a escribir las clases que interactúan con los servicios externos para que interactúen con las clases contenedoras en su lugar. Entonces es fácil probarlos en una unidad, solo tiene que burlarse de las clases de envoltura.

+0

Gracias David. Mis servicios externos están muy bien resumidos, cada uno está envuelto con una única clase de servicio Spring singleton. Incluso con esto, para un escenario complicado, la burla se vuelve difícil. Hay una gran cantidad de datos que deben ser eliminados, a menudo se llamará al mismo método de servicio muchas veces, lo que significa que necesito que los talones devuelvan valores múltiples, luego está el problema de inyectarles inyecciones con Spring ... se pone peluda. Tengo que suponer que la gente ha resuelto esto de una manera más limpia –

+0

¿Tienen que ser envueltos con un singleton? Los Singleton son notoriamente difíciles de burlar. ¿Puedes diseñar cosas para que el contenedor no sea un singleton? –

+0

Además, preguntaría por qué se llama al mismo método de servicio muchas veces en una prueba. Tal vez sus métodos de prueba son demasiado grandes? Creo firmemente en la regla del "método de una afirmación por prueba"; Realmente hace pruebas mucho más limpias. –

0

Si hay algún marco de simulación http o resto, usar eso debería ser bueno.

Todas las dependencias complicadas se pueden grabar, modificar y reproducir.

Cuestiones relacionadas