Sunday, March 16, 2008

Using DBUnit with Grails

I usually use DBUnit when writing integration tests that interact with the database. DBUnit allows me to setup an integration test to get the database into a particular state that your test may be expecting. For example if you have an integration test to insert data into a comments table, you may want to pre-load the database with a blog posting. Your integration test case is to test the insertion of comments and not blog posts. You probably already have another test case for insertion of blog posts.

DBUnit comes from the Java world, but since "Groovy is Java" you can effortlessly integrate DBUnit into your Groovy and/or Grails project. For a Grails project simply place the dbunit jar file into the "lib" directory.

When I wrote my first integration test with DBUnit my setup method looked something like this:

def sqlConnection = Sql.newInstance(
'jdbc:mysql://localhost:3306/test3',
'sp', 'sp',
'com.mysql.jdbc.Driver')


However I noticed that my test wasn't very DRY (Don't Repeat Yourself). I have already specified the connection info for my test database inside DataSource.groovy. So now I had to specify my database connection info twice, once inside DataSource.groovy and once inside my test. What would happen if someone downloaded my source code and changed only DataSource.groovy for their enviornment? Well the tests would fail miserably. Also as the number of integrations tests would grow, so would be the number of times I violated the DRY principle.

So how did I overcome these challenges? First of all I created a class called MyIntegrationTestCase that all my integration tests will extend, instead of GroovyTestCase. Actually MyIntegrationTestCase just extends GroovyTestCase. Next instead of hard coding connection info inside MyIntegrationTestCase I read the connection info from DataSouce.groovy.

Here is my class MyIntegrationTestCase:

class MyIntegrationTestCase extends GroovyTestCase {
def dataSourceConfig

def getDBUnitConnection() {
def sqlConnection = Sql.newInstance(dataSourceConfig.url,
dataSourceConfig.username,
dataSourceConfig.password,
dataSourceConfig.driverClassName)
return new DatabaseConnection(sqlConnection.connection)
}

void setUp() {
dataSourceConfig =
ApplicationHolder.application.config.dataSource
}

}


I hope this helps you integrate DBUnit in your Grails applications.

2 comments:

Andres Almiray said...

You can also use an implementation of IDatabaseTester to accomplish the setup of your testcases (there are 4 basic implementations provided by DbUnit 2.2)

Unknown said...

what version of Grails are you using?

With 1.0.3, I get null when I invoke ApplicationHolder.application and can't seem to be able to get the reference to the GrailsApplication.