September 30, 2006
Setting up HSQL and Hibernate for Unit tests
The scenario
You are developing an application where you heavily rely on a database and want it to be tested during your unit tests. In my case I have an application that uses Hibernate that is connected to an Oracle database for it’s data persistence. Now I want to write some Unit Tests, using JUnit, to see wether all works fine and my objects get serialized and restored correctly. Usually I would have to set up another database with my structure and then test it on that, but JUnit explicitly discourages this as it requires you to setup the same environment on all machines that will test the code.The solution
The solution is HSQLDB. HSQLDB is the leading SQL relational database engine written in Java. It has a JDBC driver and supports a rich subset of ANSI-92 SQL (BNF tree format) plus SQL 99 and 2003 enhancements. Along many other features it can also run in a memory resident mode, that will keep all of its data in memory and it is lost after the execution finishes. At first sight this may seem a useless feature, but think about what exactly you need when running unit tests: a simple to set up database, that is freshly instantiated with every run. And HSQL is easy to set up, in fact so easy that a single line makes all the difference.So what once was my hibernate configuration file:
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
<property name="connection.url">jdbc:oracle:thin:@hostname:1526:orcl</property>
<property name="connection.username">username</property>
<property name="connection.password">password</property>
<property name="connection.pool_size">10</property>
<property name="dialect">org.hibernate.dialect.Oracle9Dialect</property>
<property name="current_session_context_class">thread</property>
<property name="cache.provider_class">org.hibernate.cache.SwarmCacheProvider</property>
<property name="show_sql">true</property>
<mapping resource="events/Event.hbm.xml">
</mapping>
</session-factory>
</hibernate-configuration>
Now becomes this:
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">org.hsqldb.jdbcDriver</property>
<property name="connection.url">jdbc:hsqldb:mem:somename</property>
<property name="connection.username">sa</property>
<property name="connection.password"></property>
<property name="connection.pool_size">1</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.HSQLDialect</property>
<!-- Enable Hibernate's automatic session context management -->
<property name="current_session_context_class">thread</property>
<!-- Disable the second-level cache -->
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<!-- Drop and re-create the database schema on startup -->
<property name="hbm2ddl.auto">create</property>
<mapping resource="events/Event.hbm.xml">
</mapping>
</session-factory>
</hibernate-configuration>
Special attention is needed with the connection.url property and the hbm2ddl.auto property which tell hibernate to use a memory resident HSQL Database and to create the database structure at startup, which is exactly what we need for our Unit-Tests. Now for this to run you only need to include the HSQLDB Jar in your classpath and everything will run as it used to, only that it is much easier to test in a new environment, thus making it perfect for continouuous integration.To sum it all up here are the steps to migrate to HSQL for testing:
- Add HSQLDB to your classpath
- Set the driverclass to org.hsqldb.jdbcDriver
- Set the dialect to org.hibernate.dialect.HSQLDialect
- Set the database URL to jdbc:hsqldb:mem:somename
- Run your tests
powered by performancing firefox