Java 使用JPA和JUnit测试时如何一致地擦除内存数据库中的H2

Java 使用JPA和JUnit测试时如何一致地擦除内存数据库中的H2,java,spring,jpa,junit,flyway,Java,Spring,Jpa,Junit,Flyway,我的设置是这样的 H2内存中数据库使用JPA连接持久性上下文使用Spring配置。数据库设置脚本通过Flyway运行,以生成我的表和外接程序数据 数据库URL:jdbc:h2:mem:test\u数据 在我们的JUnit测试中,我们有如下设置和拆卸方法 @Override protected void setUp() throws Exception { this.context = new ClassPathXmlApplicationContext("classpath:/DataC

我的设置是这样的

H2内存中数据库使用JPA连接持久性上下文使用Spring配置。数据库设置脚本通过Flyway运行,以生成我的表和外接程序数据

数据库URL:jdbc:h2:mem:test\u数据

在我们的JUnit测试中,我们有如下设置和拆卸方法

@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测试都获得自己的数据库,这有时似乎确实有效,但有时似乎我获得的数据库与之前的测试相同。例如,我有两个测试:

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());
}
public void testGetFoos()
{       
集合foos=data.getFoos();
assertEquals(FOOS的数量,FOOS.size());
}
public void testSaveFoos()
{       
Foo bar=makeDummyFoo();
data.saveFoo(bar);
集合foos=data.getFoos();
assertEquals(FOOS的数量+1,FOOS.size());
}
这些方法应该能够以任何顺序运行,并且在运行maven构建时(看起来是这样),它们能够独立运行而不会相互影响,但是偶尔在从eclipse单独运行JUnit测试类时,save方法将首先运行,然后,get方法将运行并获得错误的计数,因为它在mem数据库中似乎与前面的测试方法获得了相同的计数


所以我的问题是如何在JUnit测试之间使用我的Spring设置杀死内存中的H2数据库?或者,如果context.close()方法是正确的,是什么导致它无法正常关闭?

我建议您使用:

  • @测试方法的测试注释
  • @安装前
  • @拆散后
您可以将此代码放在@Before中,以确保所有@Test方法都有新的db

Connection connection = DriverManager.getConnection("jdbc:h2:~/test", "sa", "");
Statement stmt = connection .createStatement()
stmt.execute("DROP ALL OBJECTS");
connection.commit();
connection.close();
我相信使用会是一个更好的方法;正是为了这个目的。看一看

祝您好运。

在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
}

Spring还有一个更紧密的集成--