我的设置是这样的。
连接到使用JPA的内存数据库中的H2,使用Spring配置持久化上下文。数据库设置脚本由Flyway运行,以生成我的表并添加数据。数据库URL:jdbc:h2:mem:test_data
在我们的JUnit测试中,我们有像这样的setUp和tearDown方法
@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;
}
这里的目的是让每个JUnit测试都能获得它自己的数据库,这似乎有时会起作用,但似乎有时我看起来像是在获得与之前测试相同的数据库。一个例子是我有2个测试:
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());
}
这些方法应该能够以任何顺序运行,并且在运行看似情况的maven构建时,它们能够独立运行而不会相互影响,但是偶尔从eclipse中单独运行JUnit测试类时保存方法将首先运行,然后get方法将运行并得到错误的计数,因为它似乎在mem数据库中与之前的测试方法相同。
所以我的问题是如何使用我的Spring设置在JUnit测试之间杀死内存数据库中的H2?或者什么可能导致它没有正确关闭,如果context.close()方法是正确的方法?
答案 0 :(得分:1)
我相信使用DbUnit会是一种更好的方法;它的目的正是为了这个目的。看看吧。
祝你好运。答案 1 :(得分:0)
我建议您使用:
您可以将此代码放在@Before中,以确保所有@Test方法都有新的db
Connection connection = DriverManager.getConnection("jdbc:h2:~/test", "sa", "");
Statement stmt = connection .createStatement()
stmt.execute("DROP ALL OBJECTS");
connection.commit();
connection.close();
答案 2 :(得分:0)
您可以使用Spring's @Sql annotation在junit测试的每个测试方法之后设置和拆除数据库,如下所示:
@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
}