Spring4 JUnit 测试:将 SQL 加载到 H2 数据库

Spring4 JUnit tests : Load SQL to a H2 db

我正在尝试为 Spring 启动 (Spring 4) 应用程序编写测试。

我的 Junit 测试 class 是这样配置的,以允许自动装配。

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = SpringApp.class)
public class MyServiceTest {
...

我的src/main/resources/application.properties是这样的

spring.jpa.database=POSTGRESQL
spring.jpa.show-sql=false
spring.jpa.hibernate.ddl-auto=update

spring.datasource.driverClassName=org.postgresql.Driver
spring.datasource.url=jdbc:postgresql://localhost/mydb
spring.datasource.username=BNF0016779
spring.datasource.password=

在测试上下文中,src/test/resources/application.properties 是空的。

可以像往常一样查询数据库,创建对象...

但我想创建一个数据初始化 sql。

首先是一个奇怪的行为,似乎 Spring 加载了 class 路径中的任何 "schema.sql"。 不需要像下面这样的东西?

//This is not required to execute schema.sql
@Configuration
public class DatabaseTestConfig {
    @Bean
    public DataSource dataSource() {
        return new EmbeddedDatabaseBuilder()
            .setType(EmbeddedDatabaseType.H2)
            .addScript("classpath:schema.sql")
            .build();
    }
}

那么,我无法从这个 SQL 创建任何 Table。 总是收到 org.h2.jdbc.JdbcSQLException: Table "MY_TABLE" already exists; SQL statement:

H2 应该是内存数据库,两次启动之间不保存数据! 为什么我会收到这些错误?

有什么想法吗? 谢谢

H2可以在内存中。但我假设它使用的默认 DataSource 不是。

您可以在 EmbeddedDatabaseBuilder 上设置 DataSourceFactory 以生成与 url 连接的 DataSource,例如 jdbc:h2:mem:test

Spring 默认情况下,引导实际上会在类路径的根目录中执行名为 schema.sql 的文件。此外,Spring Boot 还将自动为您的应用程序创建一个嵌入式数据库,除非您另有指示。有关详细信息,请参阅 Spring 引导参考手册的“Initialize a database using Spring JDBC”部分。

H2 is supposed to be a in-memory DB, no keeping data between two startup !

是也不是。

如果 Spring Boot 为您创建一个嵌入式 H2 数据库,是的,它将 内存中

但是,数据库实际上是 ApplicationContext 中的一个 bean(就像任何其他 Spring 管理的组件一样)。因此它 live 只要 ApplicationContext 存在,并且 Spring TestContext Framework 缓存测试之间的上下文:这是一个它的主要特点。换句话说,嵌入式数据库将 不会 在测试之间重新创建(除非您使用 @DirtiesContext 注释您的测试 类 或测试方法)。有关详细信息,请参阅 Spring 框架参考手册的 Context caching 部分。

此致,

Sam(Spring TestContext Framework 的作者)