Taller de Test Unitarios
Todos sabemos de la importancia de tener tests unitarios en nuestros proyectos, el problema es que cuando hay un deadline a la vuelta de la esquina, los primeros que brillan por su ausencia son los tests unitarios.
Es como una vez dijo mi amigo Ale Feltes
Hacer test unitarios es como comer de forma saludable. Todos sabemos que tenemos que hacerlo pero nunca lo hacemos.
Otro problema surge cuando no nos sentimos cómodos al momento de escribir tests, ya sea porque no sabemos por donde empezar o bien no tenemos las herramientas necesarias en nuestros proyectos para poder escribirlos. Esto último sobre todo se aplica para los tests de integración, donde generalmente tenemos que tocar una base de datos de testing y otros servicios, y configurar todo eso puede llegar a ser un verdadero dolor de cabeza.
Motivados por lo anterior, decidimos hacer el pasado día sábado 8 de octubre, una capacitación de Tests Unitarios en Sodep, donde me tocó preparar algunos ejercicios para martillar los conceptos básicos (y no tan básicos) de testing. Y también por supuesto aprovechamos la ocasión para comer mucha chipa patrocinada por Leti Pfannl :D.
Para el taller preparé una aplicación Spring Boot de ejemplo, con el objetivo de escribir tests sobre la misma y al mismo tiempo ir repasando los conceptos más importantes de Testing. La aplicación y los ejercicios los publiqué en este repositorio GitHub.
El repositorio lo preparé incluso para que se pueda seguir el taller de forma no presencial, así que si estas leyendo esto y querés aprender o poner a prueba tus conocimientos de testing, te recomendaría darle unos minutitos y hacer los ejercicios.
Para los tests unitarios de Servicios (clase con lógica de negocios) y Controladores usamos Mockito. Para testear de forma unitaria los Servicios, se tiene que separar las dependencias que tienen a la capa de acceso a datos, y de esa forma poder testearlos en aislamiento. Mockito nos permite hacer ese aislamiento y simular las dependencias que tienen los Servicios haciendo un "mock" de las llamadas que se hacen a la base de datos.
// Mock de acceso a Datos
when(movieRepo.findByTitle("Man of Steel""))
.thenReturn(new Movie("Man of Steel"));
Movie movie = movieService.getByTitle("Man of Steel");
assertThat(movie.getTitle()).isEqualTo("Man of Steel");
Para escribir las aserciones usamos la librería AssertJ, que provee una API más fluida y declarativa, en comparación con el API que ofrece JUnit en su clase Assert
. Por ejemplo, el trabajo de hacer una aserción para cada uno de los valores en una lista, se simplifica mucho utilizando AssertJ.
assertThat(movies).contains("Man of Steel", "Inception", "Conjuro");
Tanto Mockito como AssertJ ya vienen incluidos en Spring Boot al incluir la dependencia spring-boot-starter-test
en el pom.xml
.
Como corolario del taller llegamos a la conclusión de que no solamente es importante tener test unitarios, sino también es importante escribir buenos tests unitarios, usando las herramientras, librerias y prácticas adecuadas. Una vez que los tests forman parte nuestro code base, tienen que pasar por el mismo cuidado que el resto del código. Es la única forma que en el eventual caso que fallen debido a un cambio introducido en el código, los tests puedan evolucionar de forma fácil con el resto de nuestro proyecto, y no tengamos que agregar el famoso -DskipTests
al servidor de CI ;).