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

Posted

技术标签:

【中文标题】Spring4 JUnit 测试:将 SQL 加载到 H2 数据库【英文标题】:Spring4 JUnit tests : Load SQL to a H2 db 【发布时间】:2015-05-01 05:56:29 【问题描述】:

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

我的 Junit 测试类被配置为允许自动装配。

@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 在类路径中加载了任何“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 创建任何表。 总是收到org.h2.jdbc.JdbcSQLException: Table "MY_TABLE" already exists; SQL statement:

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

有什么想法吗? 谢谢

【问题讨论】:

【参考方案1】:

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

H2 应该是一个内存数据库,不会在两个数据库之间保存数据 启动!

是和不是。

如果 Spring Boot 为您创建了一个嵌入式 H2 数据库,是的,它将是 in-memory

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

问候,

Sam(Spring TestContext 框架的作者

【讨论】:

【参考方案2】:

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

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

【讨论】:

我很确定,默认情况下,它在内存中 是的,刚刚检查了 4.1.3.RELEASE 的 grepcode,它默认在内存中,我的错

以上是关于Spring4 JUnit 测试:将 SQL 加载到 H2 数据库的主要内容,如果未能解决你的问题,请参考以下文章

Spring Hibernate H2 Junit 测试 - 如何在启动时加载模式

是否可以仅使用 junit 5 将 spring 安全配置加载到我的测试中?

Junit加载Spring容器作单元测试

从 ant 执行的 junit 测试未加载 DLL

运行 Junit 测试用例时“加载 ApplicationContext 失败”

新手入门JUnit单元测试