A veces me da por hacer test de Junit, sobre todo con código nuevo o cuando tengo que tocar código existente del que no me fio mucho o no tengo controlado.
Y en esta me he tropezado y me ha encantado Mockito.
En el proyecto en el que ando metido se usa mucho Spring Framework y hay muchas clases ya hechas que son instanciadas por Spring y que reciben por inyección otras clases también instanciadas por Spring. Spring ofrece un entorno de test para poder instanciar esta clase con todas sus inyecciones, pero el asunto se complica si estas inyecciones tienen a su vez otras y los test se hacen lentos si por cada test hay que levantar un entorno de Spring.
Y aqui es donde me ha gustado Mockito. Sin entorno Spring, levanto mi clase bajo test y todo lo que spring le inyecta, lo hago con Mocks de mockito. Es bastante inmediato y rápido.
Luego ya queda en los test ir diciéndolo a Mockito qué debe devolver cuando llaman a sus métodos con determinados parámetros (eso se puede liar) y capturar las llamadas a otros métodos para ver si se les ha llamado con los parámetros correctos.
Así que he escrito un ejemplo sencillo con mockito.
Por cierto, mi idea inicial era aprovechar y escribir el ejemplo con Junit5, pero he desistido. Poniendo las dependencias de JUnit5 que se me ocurrieron, no conseguí que al ejecutar los test desde Intellij IDEA detectara que había test. Ejecutando con gradle ni idea si ha detectado o no test, porque no he visto nada relativo a test.
Supongo que es cuestión de leer un poco y funcionará, pero no me ha gustado lo no intuitivo que es. En documentación no dice cuales son las dependencias básicas a poner para que funcione y yo poniendo las que me ha parecido no lo he conseguido rápidamente.
Pienso que todo depende del tipo de tests que sean. Para pruebas unitarias, idealmente, es como extraer la clase del proyecto, y probarla individualmente, sin dependencias de ningún tipo. Si las hay, estas deberían ser cambiadas por mocks y stubs.
Luego, las pruebas de integración, si deberían hacerse con un entorno simulado, pero ya con todas las dependencias, aquí entra Spring, CDI, etc., y a veces aprovechan algún soporte de testing provisto por los mismos frameworks.
Finalmente, si son pruebas e2e, de aceptación, QA, suelen hacerse también en un entorno simulado (seedeado), y se hacen desde «afuera». Es decir, para una API es vía curl, http-client, etc., y si es una web es vía Selenium WebDriver y cía.
Las pruebas unitarias, deberían poder correrse rápidamente y rutinariamente en cada compilación. Las otras, sólo en el despliegue o diariamente de forma independiente. Pero igual hay mil maneras de organizarlo, y cada proyecto tiene necesidades distintas, ni necesita de todo esto. En general, trato de incorporar unitarias y algún tipo de integración, al menos en el backend. Cuando se encuentran bugs, en lo posible trato de crear una prueba unitaria de regresión.