Hoàng Long
Hoàng Long

Reputation: 10848

Spring Web Unit test - How to get Database to a known state?

As the title says, I want to get my database to a "known state" to apply unit test. I can drop - recreate my database every time before running unit test, but is there any better way?

My web-application currently works with Spring context & Hibernate.

Upvotes: 2

Views: 589

Answers (2)

TrueDub
TrueDub

Reputation: 5070

I'd suggest you use a tool called DBUnit - which is designed to do exactly what you're looking for. There are loads of examples on the web of using it with Spring & Hibernate.

To load the data:

@Before
public void onSetUpInTransaction() throws Exception {
    Connection conn = dataSource.getConnection();
    try {
        IDatabaseConnection connection = new DatabaseConnection(conn);
        DatabaseConfig config = connection.getConfig();
        config.setProperty(DatabaseConfig.PROPERTY_DATATYPE_FACTORY,
                new HsqldbDataTypeFactory());
                    DataFileLoader loader = new FlatXmlDataFileLoader();
            IDataSet ds = loader.load(TEST_DATA_FILE_CLUB);
                    DatabaseOperation.CLEAN_INSERT.execute(connection,ds);
            } finally {
        DataSourceUtils.releaseConnection(conn, dataSource);
    }
}

This will take the XML file referenced in the TEST_DATA_FILE_CLUB string and load it into a clean in-memory copy of the database.

To clean down, simply have another method, annotated with @After, and use the DELETE_ALL database operation instead.

Assuming you're using JUnit, placing these methods in your test class, or in a superclass that test classes can extend, will allow you to set up the database exactly as you wish for each individual test, speedily.

The XML files to load are simple:

<?xml version="1.0" encoding="UTF-8"?>
<dataset>
    <competition competitionId="1" competitionName="Competition 1"
        senior="1" junior="0"/>
</dataset>

will load an row into the competition table, with column values as specified. The senior & junior columns are booleans.

Upvotes: 3

Ralph
Ralph

Reputation: 120811

If you are doing some kind of integration tests, then try to desing the tests so that each of them works no matter if an other one fails.

Then you need to setup the database only once (before the first test)

Btw: I strongly recommend to use different database (one for development) and one that is only used for the tests.

More technical details: * if you use an inmemmory db for small and medium tests you can use spring jdbc support

<jdbc:embedded-database id="dataSource" type="H2" >
    <jdbc:script location="classpath:init.sql" />       
</jdbc:embedded-database>

Upvotes: 1

Related Questions