
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):
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package es.com.blogspot.elblogdepicodev.hibernate; | |
import java.util.Date; | |
import javax.persistence.EntityManager; | |
import javax.persistence.EntityManagerFactory; | |
import javax.persistence.Persistence; | |
import org.junit.After; | |
import org.junit.AfterClass; | |
import org.junit.Assert; | |
import org.junit.Before; | |
import org.junit.BeforeClass; | |
import org.junit.Test; | |
import es.com.blogspot.elblogdepicodev.hibernate.dao.GenericDAO; | |
import es.com.blogspot.elblogdepicodev.hibernate.dao.GenericDAOImpl; | |
import es.com.blogspot.elblogdepicodev.hibernate.dao.GenericSearchDAO; | |
import es.com.blogspot.elblogdepicodev.hibernate.dao.GenericSearchDAOImpl; | |
public class HibernateTest { | |
private static EntityManagerFactory entityManagerFactory; | |
private static EntityManager entityManager; | |
private static GenericDAO dao; | |
private static GenericSearchDAO sdao; | |
private static Producto producto; | |
@BeforeClass | |
public static void beforeClass() { | |
entityManagerFactory = Persistence.createEntityManagerFactory("h2"); | |
entityManager = entityManagerFactory.createEntityManager(); | |
dao = new GenericDAOImpl(Producto.class, entityManager); | |
sdao = new GenericSearchDAOImpl(Producto.class, entityManager); | |
} | |
@AfterClass | |
public static void afterClass() { | |
entityManager.close(); | |
entityManagerFactory.close(); | |
} | |
@Before | |
public void before() throws Exception { | |
entityManager.getTransaction().begin(); | |
producto = new Producto( | |
"Tapestry 5 - Rapid web application development in Java", | |
"Rapid web application development in Java is a comprehensive guide, introducing Apache Tapestry and its innovative approach to building modern web applications. The book walks you through Tapestry 5, from a simple Hello World application to rich Ajax-enabled applications. Written by a core committer this book provides deep insight into the architecture of Tapestry 5. It not only shows you how to achieve specific goals but also teaches you the \"why\". You learn how to build modern, scalable Web 2.0 application with a component-oriented approach. This book also shows how Tapestry brings scripting language productivity within reach of Java developers without sacrificing any of Java's inherent speed and power.", | |
10l, new Date()); | |
dao.persist(producto); | |
entityManager.getTransaction().commit(); | |
} | |
@After | |
public void after() throws Exception { | |
entityManager.getTransaction().begin(); | |
dao.removeAll(); | |
entityManager.getTransaction().commit(); | |
} | |
@Test | |
public void findAll() { | |
Assert.assertEquals(1, dao.findAll().size()); | |
} | |
@Test | |
public void countAll() { | |
Assert.assertEquals(1, dao.countAll()); | |
} | |
@Test | |
public void remove() { | |
entityManager.getTransaction().begin(); | |
dao.remove(producto); | |
entityManager.getTransaction().commit(); | |
Assert.assertEquals(0, dao.countAll()); | |
} | |
@Test | |
public void removeAll() { | |
entityManager.getTransaction().begin(); | |
dao.removeAll(); | |
entityManager.getTransaction().commit(); | |
Assert.assertEquals(0, dao.countAll()); | |
} | |
@Test | |
public void search() throws InterruptedException { | |
sdao.indexAll(); | |
Assert.assertEquals(1, sdao.search("Tapestry", "nombre", "descripcion").size()); | |
} | |
} |
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:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ git clone git://github.com/picodotdev/elblogdepicodev.git | |
$ cd elblogdepicodev/HelloWorldHibernate | |
$ ./gradlew test |
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