I have begun evaluating liquibase. So far I think it will be extemely
useful for our team.
I am trying to use it in the context of unit testing. I'd like to
ensure that my testing database matches our released database schema. I
am using the spring framework and junit 4 for my testing harness. I
utilize the SpringLiquibase object to load our tables for the tests.
This works great for creating the tables, but once the tests are done,
there is no clean way to unload all of the changes I just made to ensure
that the database is in the same state as when I started.
I know I can utilize the Liquibase object in @Before and @After methods
to load and unload the tables. And for now, I have implemented that.
<bean name="liquibase" class="liquibase.Liquibase">
<constructor-arg index="0" value="phonebook-create-changelog.xml"/>
<constructor-arg index="1">
<bean class="liquibase.ClassLoaderFileOpener"/>
</constructor-arg>
<constructor-arg index="2">
<bean id="dataSource.connection"
class="org.springframework.beans.factory.config.PropertyPathFactoryBean"
/>
</constructor-arg>
</bean>
@Resource
private Liquibase liquibase;
private void create_tables() throws Throwable {
liquibase.update("");
}
@After
public void drop_tables() throws Throwable {
liquibase.rollback(Integer.MAX_VALUE, "");
}
@Before
public void setup_database() throws Throwable {
create_tables();
load_test_data();
}
I would prefer if the SpringLiquibase object had something like a
rollbackOnDestroy() that would allow spring to trigger a rollback when
it unloaded the application context. You could configure it like this:
<bean name="spring.liquibase" class="liquibase.spring.SpringLiquibase"
destroy-method="rollbackOnDestroy">
<property name="dataSource" ref="dataSource"/>
<property name="changeLog"
value="classpath:phonebook-create-changelog.xml"/>
<property name="contexts" value="test, production"/>
</bean>
The rollbackOnDestroy method would only be called if it was configured.
I am rolling back to Integer.MAX_VALUE because I want everything rolled
back so that my database is empty before and after any test, but that
could be added as a configured property on the SpringLiquibase object
such as maxChangeRollbackCount.
I threw together a quick attempt at implementing this:
/**
* Optionally executed when bean is destroyed
*/
public void rollbackOnDestroy() throws LiquibaseException {
Connection c = null;
try {
c = getDataSource().getConnection();
Liquibase liquibase = createLiquibase(c);
liquibase.rollback(Integer.MAX_VALUE, getContexts());
} catch (SQLException e) {
throw new JDBCException(e);
} finally {
if (c != null) {
try {
c.rollback();
c.close();
} catch (SQLException e) {
//nothing to do
}
}
}
}
Something along these lines would be a good enhancement to the
SpringLiquibase object, and would greatly assist with testing.
Unfortunately the maven plugin doesn't help here as there is no maven
lifecycle event such as after-test to ensure that things happen after
the unit tests when a user types mvn test.
JB
"The best way to predict the future is to invent it."
- Alan Kay
------------------------------------------------------------------------------
This SF.net email is sponsored by Sprint
What will you do first with EVO, the first 4G phone?
Visit sprint.com/first -- http://p.sf.net/sfu/sprint-com-first
_______________________________________________
Liquibase-user mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/liquibase-user