Thursday, May 20, 2010

Performance Improvements for DAO Testing in an ORM environment

In any good size project using an ORM tool such as Hibernate, you are bound to have a good number of DAO classes that encapsulate persistent interactions. Running JUnit tests against your DAO's can take some time with ANT, as a new Session Factory is instantiated for each Unit Test. In a current project the time to run the tests in our DAO package was about three minutes. I found a solution that cut the time to run all the tests down to 40 seconds. The solution : Junit TestsSuite.

The TestSuite instantiates the SessionFactory once, and all the tests reuse the instance. The code:

public class DaoTestSuite extends TestCase{

public static Test suite(){
TestSuite suite = new TestSuite();
suite.addTestSuite(DaoTest1.class);
suite.addTestSuite(DaoTest2.class);

// and so on ... or you could do this reflectively

suite.addTestSuite(DaoTestN.class);


TestSetup wrapper = new TestSetup(suite){
protected DbUtil dbUtil = new DbUtil();

@Override
protected void setUp(){
//Before the suite, we configure the factory
dbUtil.beginConversationThread();
}


@Override
protected void tearDown(){
//After the suite, we ensure the factory is closed
dbUtil.rollbackTransaction();
}
};

return wrapper;
}



The DbUtil class is a standard ORM class that configures the SessionFactory, ensures that a session is open, transaction is active, and provides a means to rollback the transaction.

The Test classes that are added to the suite have the following before and after methods:

protected DbUtil _dbUtil = new DbUtil();


public void setUp() {
_dbUtil.beginConversationThread();
}


public void tearDown() {
_dbUtil.rollbackTransaction();
}


Where the beginConversationThread() call grabs an active session from the factory, or starts the factory if it is not yet configured and running. Since the TestSuite is run in one JVM, the SessionFactory is configured but once.

No comments: