Categories
Coding

Easy Testing with AbstractTransactionalSpringContextTests

Spring 1.2 has got some nice support for database testing. Specifically, it has the class AbstractTransactionalSpringContextTests, which will execute its tests within an individual transaction, and then rollback at the end of each test, unless you specify otherwise by calling setComplete(). This class in turn extends the class AbstractDependencyInjectionSpringContextTests, which uses field injection to populate its data. Field injection looks up beans in the current context by name, rather than type. So for instance, our PersistentTestCase class can now look like:

import org.hibernate.SessionFactory;
import org.springframework.test.AbstractTransactionalSpringContextTests;

public class PersistentTestCase extends AbstractTransactionalSpringContextTests
{

    protected SessionFactory testSessionFactory;   //wired by type
    protected ReferenceData referenceData;

    protected PersistentTestCase()
    {
        super();
        //setDefaultRollback(false); 
        setPopulateProtectedVariables(true);
    }


    protected String[] getConfigLocations()
    {
        return new String[]
        {
            "classpath:application_test_context.xml"
        };
    }

    protected void flushSession(){
        testSessionFactory.getCurrentSession().flush();
    }

    protected void clearSession(){
        flushSession();
        testSessionFactory.getCurrentSession().clear();
    }

    public void setReferenceData(ReferenceData p_referenceData)
    {
        referenceData = p_referenceData;
    }

}

The neat thing about this is that we have a whole bunch of reference data that is injected into the class and populated automatically – just by declaring the data as a protected field, calling setPopulateProtectedVariables(true), and declaring the reference data bean in the application-context.xml with the correct name. Field-based injection will take care of the rest. Very easy, and it makes things nice and neat. Another nice feature is that contexts can be cached, and not reloaded and reinitialized every time across tests, which can save a lot of time if you’re using Hibernate’s create-drop mode, and it spends a long time initializing constraints.