JUnit + Derby + Spring: flush db in memory after each test

In my unit tests, I mounted several DataSources that use URLs such as

jdbc:derby:memory:mydb;create=true 

to create embedded databases.

To remove the embedded Derby db, you need to connect to:

 jdbc:derby:memory:mydb;drop=true 

I would like this to happen after each test and start with a new db. How to do this using Spring?

+6
java spring junit derby in-memory-database
source share
6 answers

How to shut down Derby database in memory correctly

gave me a hint:

  mydb.drop.url = jdbc:derby:memory:mydb;drop=true ... <bean id="mydbDropUrl" class="java.lang.String"> <constructor-arg value="${mydb.drop.url}" /> </bean> ... @Resource private String mydbDropUrl; @After public void tearDown() { try { DriverManager.getConnection(mydbDropUrl); } catch (SQLException e) { // ignore } } 

The downside is the use of the String constructor, which takes a String (immutable String object around an immutable String object). I read that in Spring 3 there is an @Value annotation that may help here, but I am using Spring 2.5.

Please let me know if you have a more pleasant solution.

+4
source share

There is an agnostic way to create a database if you use Spring with Hibernate.

Ensure that the application context is created / destroyed before / after each testing method:

 @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration({"classpath*:application-context-test.xml"}) @TestExecutionListeners({DirtiesContextTestExecutionListener.class, DependencyInjectionTestExecutionListener.class}) @DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD) public abstract class AbstractTest { } 

To instruct Hibernate to automatically create a diagram at startup and abandon the diagram at shutdown:

 hibernate.hbm2ddl.auto = create-drop 

Now before each test

  • the application context is created and the necessary Spring beans (spring) are introduced
  • database structures are created (hibernation)
  • import.sql is executed if present (sleep mode)

and after each test

  • application context is broken (spring)
  • The database schema is discarded (sleep mode).

If you use transactions, you can add a TransactionalTestExecutionListener .

+5
source share

After spring test 3, you can use annotations to enter configurations:

 @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("/spring-test.xml") public class MyTest { } 
+2
source share

If you use the spring -test.jar library, you can do something like this:

 public class MyDataSourceSpringTest extends AbstractTransactionalDataSourceSpringContextTests { @Override protected String[] getConfigLocations() { return new String[]{"classpath:test-context.xml"}; } @Override protected void onSetUpInTransaction() throws Exception { super.deleteFromTables(new String[]{"myTable"}); super.executeSqlScript("file:db/load_data.sql", true); } } 

And an updated version based on the last comment, which removes the db and recreates the tables before each test:

 public class MyDataSourceSpringTest extends AbstractTransactionalDataSourceSpringContextTests { @Override protected String[] getConfigLocations() { return new String[]{"classpath:test-context.xml"}; } @Override protected void onSetUpInTransaction() throws Exception { super.executeSqlScript("file:db/recreate_tables.sql", true); } } 
+1
source share

Just do something like:

 public class DatabaseTest implements ApplicationContextAware { private ApplicationContext context; private DataSource source; public void setApplicationContext(ApplicationContext applicationContext) { this.context = applicationContext; } @Before public void before() { source = (DataSource) dataSource.getBean("dataSource", DataSource.class); } @After public void after() { source = null; } } 

Make your bean the volume of the prototype ( scope="prototype" ). This will give a new instance of the data source before each test.

+1
source share

This is what we do at the beginning of each test.

  • Discard all previous objects.

  • Create all the tables mentioned in the create_table.sql file

  • Paste the values ​​into the created tables based on what you want to check.

      @Before public void initialInMemoryDatabase() throws IOException, FileNotFoundException { inMemoryDerbyDatabase.dropAllObjects(); inMemoryDerbyDatabase.executeSqlFile("/create_table_policy_version_manager.sql"); inMemoryDerbyDatabase.executeSqlFile("/insert_table_policy_version_manager.sql"); } 

It works like a charm!

0
source share

All Articles