DBUnit es un sistema sencillo que nos permite cargar con datos nuestra base de datos con el fin de realizar tests con estos datos.
La gran ventaja de DBUnit es poder utilizar un sistema sencillo para indicar los datos a insertar mediante un XML, así como poder exportar una BBDD existente.
Sin embargo, DBUnit no permite la creación de la BBDD, lo que puede ser un problema al intentar usar una BBDD en memoria, como pueda ser HyperSQL o Derby.
Enunciado
Como me gusta resolver los problemas concretos y no los abstractos, veamos cómo usar DBUnit con una base de datos en memoria. Para ello utilizaremos un pequeño gestor de libros con una única tabla, que contendrá el id, título y autor.
Datos
Nuestros datos serán los siguientes:
1
2
3
4
5
6
<?xml version="1.0" encoding="UTF-8"?><dataset><bookid="1"title="Fundación"author="Isaac Asimov"/><bookid="2"title="Clean Code"author="Robert C. Martin"/><bookid="3"title="Diseño ágil con TDD"author="Carlos Ble"/></dataset>
Aquí ya estamos diseñando. Lo que le estamos diciendo a DBUnit es que vamos a tener una tabla “book” con 3 columnas, que son “id”, “title” y “author”.
El archivo anterior se situará en el paquete “tests”, de manera que se empaquetará en el JAR con nuestras pruebas.
publicclasstest1extendsDBTestCase{static{try{Stringdriver="org.hsqldb.jdbcDriver";Stringurl="jdbc:hsqldb:mem:sample";Stringuser="sa";Stringpass="";System.setProperty(PropertiesBasedJdbcDatabaseTester.DBUNIT_DRIVER_CLASS,driver);System.setProperty(PropertiesBasedJdbcDatabaseTester.DBUNIT_USERNAME,user);System.setProperty(PropertiesBasedJdbcDatabaseTester.DBUNIT_PASSWORD,pass);Class.forName(driver);Connectioncon=DriverManager.getConnection(url,user,pass);st.execute("create table book ("+"id integer, "+"title varchar(50), "+"author varchar(50)"+")");con.close();}catch(Exceptione){e.printStackTrace();}}@OverrideprotectedIDataSetgetDataSet()throwsException{InputStreamfile=getClass().getResourceAsStream("/tests/test1.xml");IDataSetresult=newFlatXmlDataSet(file);returnresult;}@Testpublicvoidtest1()throwsException{IDatabaseConnectionconn=getConnection();assertEquals(3,conn.getRowCount("book"));conn.close();}}
Desglosando el código
Veamos ahora qué es lo que hemos hecho.
Lo primero es indicar que nuestro código hereda de DBTestCase. Eso nos obliga a implementar el método abstracto getDataSet. Este método le indica a DBUnit los datos con los que rellenar la BBDD antes de cada test.
Con esto sería suficiente como para que DBUnit pueda ejecutarse sin problemas, pero la tabla “Book” no existe. Así que lo solucionamos con el acceso estándar a BBDD de Java:
1
2
3
4
5
6
7
8
9
Class.forName(driver);Connectioncon=DriverManager.getConnection(url,user,pass);Statementst=con.createStatement();st.execute("create table book ("+"id integer, "+"title varchar(50), "+"author varchar(50)"+")");con.close();
<?xml version=''1.0'' encoding=''UTF-8''?><dataset><tablename="BOOK"><column>ID</column><column>TITLE</column><column>AUTHOR</column><row><value>1</value><value>Fundación</value><value><![CDATA[Isaac Asimov]]></value></row><row><value>2</value><value><![CDATA[Clean Code]]></value><value><![CDATA[Robert C. Martin]]></value></row><row><value>3</value><value><![CDATA[Diseño Ágil con TDD]]></value><value><![CDATA[Carlos Ble]]></value></row></table></dataset>
Comparando tablas
Todo lo anterior está muy bien, pero lo que de verdad nos interesa es comparar datos. El uso habitual es:
Se cargan unos datos,
se realizan operaciones,
se comprueba que los datos son correctos.
Pues esto resulta una tarea sencilla cuando se utiliza dbunit:
1
2
3
4
5
6
7
8
9
10
@Testpublicvoidtest_comparar_tablas()throwsException{IDatabaseConnectionconn=getConnection();InputStreamfile=getClass().getResourceAsStream("/tests/test2.xml");IDataSetexpected=newFlatXmlDataSet(file);ITabletable=conn.createQueryTable("books","select * from book where author != ''Isaac Asimov''");Assertion.assertEquals(expected.getTable("book"),table);conn.close();}
Como se ve, estamos cargamos un nuevo archivo de datos (test2.xml), realizamos una consulta y comparamos los resultados.
El archivo de datos cargado tendrá esta forma (en el paquete “tests”):
1
2
3
4
5
<?xmlversion="1.0"encoding="UTF-8"?><dataset><bookid="2"title="Clean Code"author="Robert C. Martin"/><bookid="3"title="Diseño Ágil con TDD"author="Carlos Ble"/></dataset>
A tener en cuenta
Hay varios puntos a tener en cuenta:
Si nuestros tests no comienzan por test, no se ejecutarán (formato de junit 3).
Podemos utilizar una BBDD en memoria para probar datos para no modificar la BBDD real. Además, resultará más rápido y cómodo.
Cuanto más pequeños sean los archivos de pruebas, serán menos propensos a cambios y más rápidos de ejecutar
Más información
Tenéis más información en la web de DBUnit , en la de JUnit y en la de
HyperSQL . También podría haberse hecho con Derby , como ya comenté.