viernes, 16 de agosto de 2013

Pruebas unitarias de código que accede a base de datos

Hibernate
Una de las dificultades que nos solemos encontrar a la hora de hacer pruebas unitarias es como probar el código que accede a la base de datos. El problema es que ese código necesita de una base de datos para ejecutarse, si se usa una base de datos como MySQL o PosgreSQL más que una prueba unitaria puede considerarse una prueba de integración y las pruebas pasan a depender de ese sistema externo con lo que las pruebas no son autónomas.

La base de datos H2 es una base de datos que puede ser embebida en una aplicación. Esta característica hace que pueda servir como base de datos contra la que lanzar los teses sin necesidad de una base de datos externa, además puede ejecutarse en memoria y sin comunicación de red lo que hace que sea muy rápida y los teses también. Tampoco es una solución perfecta ya que H2 puede tener un comportamiento diferente de la base de datos real pero en la mayoría de los casos nos servirá perfectamente.

Siguiendo los artículos anteriores en los que explicaba como acceder a una base de datos en una aplicación Java «standalone» y como hacer búsquedas en entidades de comino usando sin utilizar likes veamos como sería hacer una prueba unitaria de ese código que accede a la base de datos usando JUnit.

El método beforeClass inicializa la persistencia y crea el DAO. El método before borra los datos que haya creado un test anterior y crear los datos de prueba que una prueba puede esperar que existan, en este caso se trata de un único producto. Las pruebas consisten en probar el método findAll y search del DAO (el método removeAll puede considerarse probado en el before aunque podría crearse un caso de prueba específico):

En las pruebas unitarias al código que use el DAO puede proporcionársele un «stub» de este haciendo que devuelva los datos que necesitemos y sin necesidad de una base de datos como H2 pero para probar el DAO hay que disponer de una base de datos. Como es código que también puede contener fallos es bueno que también esté cubierto con algunas pruebas. Con Hibernate todo será más sencillo ya que con este además de abstraernos de la base de datos específica puede crear el esquema con las tablas y campos a partir del modelo de forma que antes de pasar los teses no necesitemos lanzar un script con sentencias SQL para crear las tablas.

Usar H2 como la base de datos contra que lanzar las pruebas unitarias es una solución imperfecta ya que idealmente la base de datos debería ser igual a la base de datos que vaya a usar la aplicación real (probablemente MySQL o PosgreSQL). H2 tiene la ventaja de que los teses se ejecutarán más rápido que con un sistema real externo y que las pruebas son más autónomas ya que no depende de ese sistema externo, aún así si hacemos uso de elementos nativos de la base de datos y queremos que queden cubiertos con pruebas no nos quedará más remedio que disponer de una base de datos «más real» que H2 para ellas aunque como decía estas pasarán a ser más de integración que unitarias.

Como el resto de ejemplos que escribo en el blog el código fuente lo puedes encontrar en mi repositorio de GitHub. Para probar este código en tu equipo basta con ejecutar:

Referencia:
Código fuente acceso a base de datos con Hibernate y JPA http://stackoverflow.com/questions/82949/before-and-after-suite-execution-hook-in-junit-4-x