1

My set up is like this.

H2 in Memory database connected to using JPA the persistence context is configured using Spring. The database set up script is run by Flyway to generate my tables and add in data.

Database URL: jdbc:h2:mem:test_data

In our JUnit tests we have setUp and tearDown Methods like this

@Override
protected void setUp() throws Exception {
    this.context = new ClassPathXmlApplicationContext("classpath:/DataContext.xml");
    this.data = this.context.getBean(DataProvider.class);
}   

@Override
protected void  tearDown( ) throws Exception {
    this.context.close();
    this.context = null;
    this.data = null;
}

The intention here is for each JUnit test to get it's own data base, and this does seem to work sometimes, however there seem to be occasions when it appears like I am getting the same database as the previous test. An example is that I have 2 tests:

public void testGetFoos()
{       
    Collection<Foo> foos= data.getFoos();
    assertEquals(NUMBER_OF_FOOS,foos.size());
}

public void testSaveFoos()
{       
    Foo bar = makeDummyFoo();
    data.saveFoo(bar);
    Collection<Foo > foos = data.getFoos();

    assertEquals(NUMBER_OF_FOOS + 1,foos.size());
}

These methods should be able to run in any order and when running the maven build that appears to be the case, they are able to run independently without affecting each other, however occasionally when running the JUnit test class individually from eclipse the save method will run first, then the get method will run and get the wrong count because it seems to have gotten the same in mem database as the previous test method.

So my question is how to I kill my H2 in memory database between JUnit tests using my set up with Spring? or What could be causing it to not shut down properly, if the context.close() method is the correct way?

Link19
  • 586
  • 1
  • 18
  • 47

3 Answers3

1

I believe using DbUnit would be a better approach; it is intended for exactly this purpose. Give it a look.

Good luck.

Jamie Bisotti
  • 2,605
  • 19
  • 23
0

I suggest that you use :

  • @Test annotations on test methods
  • @Before on setup
  • @After on teardown

You can put this code in @Before to ensure that all @Test methods will have fresh db

Connection connection = DriverManager.getConnection("jdbc:h2:~/test", "sa", "");
Statement stmt = connection .createStatement()
stmt.execute("DROP ALL OBJECTS");
connection.commit();
connection.close();
Woody
  • 809
  • 8
  • 21
0

You could use Spring's @Sql annotation to setup and teardown the database after each test method on your junit test like this:

@SqlGroup({
    @Sql(executionPhase = ExecutionPhase.BEFORE_TEST_METHOD, scripts ="classpath:db/data.sql"), 
    @Sql(executionPhase = ExecutionPhase.AFTER_TEST_METHOD, scripts = "classpath:db/clean.sql") 
})
public void test(){
    //test logic
}
marcel
  • 1
  • 1