Estoy tratando de probar una clase que llama a algunos servicios web de Hadoop. El código es más o menos de la forma:
method() {
...use Jersey client to create WebResource...
...make request...
...do something with response...
}
por ejemplo, hay un método de creación de directorio, un método de creación de carpeta, etc.
Dado que el código trata con un servicio web externo sobre el que no tengo control, ¿cómo puedo probar esto unitariamente? Podría intentar burlarme del cliente / respuestas del servicio web, pero eso rompe la pauta que he visto mucho recientemente: "No te burles de los objetos que no tienes". Podría configurar una implementación ficticia del servicio web, ¿constituiría eso una "prueba unitaria" o sería una prueba de integración? ¿No es posible realizar una prueba unitaria a este nivel tan bajo? ¿Cómo podría hacer esto un profesional de TDD?
fuente
Respuestas:
En mi opinión, debe burlarse de las llamadas al servicio web si se trata de una prueba unitaria, en lugar de una prueba de integración.
La prueba de su unidad no debe probar si el servicio web externo está funcionando o si su integración con él es correcta. Sin entrar demasiado dogmática sobre TDD, nota que un efecto secundario de convertir su unidad de prueba en una prueba de integración es que es probable que se ejecute más lento, y desea rápidas pruebas unitarias.
Además, si el servicio web está temporalmente fuera de servicio o funciona incorrectamente, ¿esto debería causar que falle la prueba de la unidad? No parece correcto La prueba de su unidad debería fallar por una sola razón: si hay un error en el código de esa "unidad".
La única porción de código que es relevante aquí es
...do something with response...
. Burlarse del resto.fuente
No estoy de acuerdo con "no te burles de los objetos que no tienes" cuando estás probando unidades.
El propósito simulado de la existencia es el hecho de que habrá módulos, bibliotecas, clases que no poseeremos.
Mi sugerencia para su escenario es simular la llamada al servicio web.
Configure el simulacro de tal manera que devuelva los datos a su módulo.
Asegúrese de cubrir todos los escenarios, por ejemplo, cuando los datos devueltos sean nulos, cuando los datos devueltos sean válidos, etc.
Y para el código que posee, su responsabilidad como desarrollador es asegurarse de que el código que está creando funcione como se espera en todos los escenarios.
fuente
Usaría algo como EasyMock para esta prueba. Los frameworks burlones son una forma ideal de eliminar dependencias externas de una clase y le brinda control total sobre el resultado de dependencias externas durante las pruebas. Para extender un poco su ejemplo:
Lo primero que tendrá que hacer es extraer la lógica en su clase donde usa Jersey para obtener un recurso web y llamar al servicio web a una clase separada. Crear una interfaz para esta clase le permitirá crear una simulación a la que luego puede dictar el comportamiento.
Una vez que se crea esta interfaz, puede crear un simulacro con EasyMock, que devolverá un objeto específico según su caso de prueba. El ejemplo anterior es una simplificación de cómo estructurar una prueba simulada básica y cómo funcionará su interfaz.
Para obtener más información sobre los marcos de simulación, consulte esta pregunta . Además, este ejemplo supone el uso de Java, pero los marcos de simulación están disponibles en todos los idiomas y, aunque se implementan de manera diferente, generalmente funcionarán de la misma manera
fuente
Los simulacros son aceptables en este caso, pero no lo necesitas. En lugar de la prueba unitaria
method()
, prueba la unidad solo la parte que maneja la respuesta.Extraiga una función que tome
ResponseData
(del tipo que sea apropiado) y luego realice la acción.En lugar de burlarse, ahora solo construye un objeto ResponseData y lo pasa.
Puede dejar la llamada del servicio a pruebas de integración completas, que cubrirán
method()
en totalfuente
Lo que he hecho y funciona:
3.1 Primero se prueban todos los servicios web. De cada máquina, incluso las máquinas del desarrollador. Estos son los servicios web reales, pero se ejecutan en entornos de desarrollo. Esto significa que los servicios web nunca pueden estar inactivos o responder a valores erróneos, porque de lo contrario cada desarrollador se queja de que no puede compilar.
3.2 Luego se ejecutan todas las pruebas unitarias internas de la aplicación. Esto significa que todos los servicios web se burlan y prueban ejecutando las mismas pruebas que 3.1 (y también deben pasar, de lo contrario, los simulacros son incorrectos), y la aplicación real los invoca como si realmente se estuvieran utilizando. Si los simulacros son incorrectos, puede ejecutar la prueba en 3.1 y registrar esos valores (solicitud, respuesta) en un HashMap.
3.3 Luego se ejecutan las mismas pruebas que 3.2, pero esta vez contra los servicios web reales que se ejecutan en el entorno de desarrollo.
Después de completar todo esto, para el entorno de producción real solo necesita proporcionar la dirección real para cada servicio web. Esperemos que esto no requiera demasiados cambios en la configuración.
fuente