How do I use Spring embedded database initialization scripts during the integration-test phase?

Ray Toal picture Ray Toal · Aug 9, 2012 · Viewed 8.3k times · Source

I can use Spring to create and initialize embedded databases either programmatically:

@Before
public void setUp() {
    database = new EmbeddedDatabaseBuilder()
            .setType(EmbeddedDatabaseType.H2)
            .addScript("schema.sql")
            .addScript("init.sql")
            .build();
    ....
}

or via Spring configuration:

<jdbc:initialize-database data-source="dataSource">
  <jdbc:script location="classpath:schema.sql"/>
  <jdbc:script location="classpath:init.sql"/>
</jdbc:initialize-database>

Here my scripts schema.sql and init.sql are stored in the directory src/test/resources. So if tests using the embedded databse are run with:

mvn test

then the files, being in src/test/resources are available, and everything is fine.

But now suppose I want to instead use the embedded database together with an embedded web server (Jetty or embedded Tomcat) in an integration test, run via

mvn integration-test

Now in this late phase, I want to do an almost end-to-end test that hitting certain urls for the web service return the expected HTTP responses, assuming certain data in the embedded database. But at this point, the war deployed in the embedded webserver does not have files from src/test/resources so my initialization scripts are not present, and I get the error

Caused by: java.io.FileNotFoundException: class path resource [schema.sql] cannot be opened because it does not exist

Now everything will work if I put the scripts in src/main/resources but these scripts are only for filling up an embedded database for testing and they do not belong in the war file at all. Does anyone know how to set up an integration test so that an emedded database can be used, without polluting the actual war file that will be deployed?

I was hoping that Spring's embedded database initialization could use something other than a file. I thought about JNDI but that would seem to require polluting the web.xml file with a resource definition for test data which would (again) appear in the deployable war. Or perhaps there are options using cargo? Some programmatic tricks with Spring that I don't know?

Answer

Kevin picture Kevin · Aug 10, 2012

You should be able to do this:

<jdbc:initialize-database data-source="dataSource">
    <jdbc:script location="file:///${project.basedir}/src/test/resources/schema.sql"/>
    <jdbc:script location="file:///${project.basedir}/src/test/resources/init.sql"/>
</jdbc:initialize-database>