在 Spring Boot 中使用嵌入式数据库进行测试

Posted

技术标签:

【中文标题】在 Spring Boot 中使用嵌入式数据库进行测试【英文标题】:Use embedded database for test in spring boot 【发布时间】:2017-07-11 04:51:30 【问题描述】:

我有一个 Spring Boot 应用程序,它有几个 @Entity 类和 @RepositoryRestResource 存储库接口。现在我想写一些测试,在那里我可以检查我是否可以使用这些存储库将新记录添加到我的数据库中,但我不想使用我配置的 mysql 数据库,而是我想使用一些嵌入式数据库像H2。目前我有一个application.properties 文件,如下所示:

spring.jpa.hibernate.ddl-auto=create
spring.datasource.url=jdbc:mysql://localhost:3306/mydb
spring.datasource.username=root
spring.datasource.password=qwerty123

问题:如何配置我的应用以使用其他数据库进行测试?我的项目中没有xml,一切都基于注释。我尝试使用@Bean 定义@Configuration 类以创建DataSource,然后在测试类上将其与@ContextConfiguration 注释一起使用,但它说它无法加载上下文。

【问题讨论】:

【参考方案1】:

您将需要使用 Spring Profiles - https://docs.spring.io/spring-boot/docs/current/reference/html/howto-properties-and-configuration.html#howto-set-active-spring-profiles

您将使用“spring.profiles.active = development”定义一个活动配置文件,然后在您的开发配置文件中包含 H2。

这些示例使用 YAML,但它们也适用于标准属性文件。

【讨论】:

【参考方案2】:

如果您使用的是 Maven 项目,您可以将 application.properties 文件添加到您的 src/test/resources 中,例如具有以下内容。

# Create DDL
spring.jpa.hibernate.ddl-auto=create

# H2 in local file system allowing other simultaneous connections
spring.datasource.url=jdbc:h2:~/test;AUTO_SERVER=TRUE

另外,您需要包含 H2 作为依赖项 (pom.xml):

<dependency>
   <groupId>com.h2database</groupId>
   <artifactId>h2</artifactId>
   <version>1.4.193</version>
</dependency>

【讨论】:

如果我这样做,它仍然使用 MySQL db。我应该提供有关测试课程的更多信息吗?一些注释来明确定义这些属性,而不是来自main 文件夹的那些? 好的,我为测试类添加了@PropertySource("path/to/properties") 注释,现在它可以工作了,谢谢【参考方案3】:

Spring Boot 为测试提供了 2 个与 JPA 自动配置相关的神奇注解:@DataJpaTest@AutoConfigureTestDatabase。 javadoc 说:

默认情况下,使用 @DataJpaTest 注释的测试将使用嵌入的 内存数据库(替换任何显式或通常自动配置的 数据源)。 @AutoConfigureTestDatabase 注解可用于 覆盖这些设置。

如果您希望加载完整的应用程序配置,但 使用嵌入式数据库,你应该考虑结合@SpringBootTest 使用@AutoConfigureTestDatabase 而不是这个注解。

所以,你唯一需要的就是你的 pom 文件中的依赖:

    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <scope>test</scope>
    </dependency>

就是这样。但是,spring boot 规范也有 2 个有用的警告:

您无需提供任何连接 URL。你只需要包括一个 建立对您要使用的嵌入式数据库的依赖关系。 如果您在测试中使用此功能,您可能会注意到 整个测试套件都重用相同的数据库 您使用的应用程序上下文的数量。如果你想确定 每个上下文都有一个单独的嵌入式数据库,您应该设置 spring.datasource.generate-unique-name 为 true。

还有一个:

如果出于某种原因,您确实为某个连接配置了连接 U​​RL 嵌入式数据库,注意确保数据库的自动 关机被禁用。如果你使用 H2,你应该使用 DB_CLOSE_ON_EXIT=FALSE 这样做。如果你使用 HSQLDB,你应该确保 不使用 shutdown=true 。禁用数据库的自动 shutdown 让 Spring Boot 控制数据库何时关闭,从而 确保一旦不再访问数据库就会发生这种情况 需要

这几乎是您需要了解的有关 Spring Boot 和嵌入式数据库的全部内容。我认为绝对没有理由使用 test 以外的依赖范围,除非您实际上有意为应用程序运行时配置嵌入式数据库。信不信由你,仅 H2 jar 在你的肥罐内就需要 1.8M。在粒度微服务、无服务器和 lambda 函数的世界中,您在应用中放入什么内容很重要。

我还建议检查@AutoConfigureTestDatabase 中的选项。我将它与@SpringBootTest 一起使用,但它也可以与其他一些注释一起使用,即@DataJpaTest,两者都在上面提到:

【讨论】:

以上是关于在 Spring Boot 中使用嵌入式数据库进行测试的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Spring Boot 集成测试中使用嵌入式 MongoDB

Spring Boot使用嵌入式容器,自定义Filter如何配置?

在 Spring Boot 中进行选择语句时,HSQLDB 用户缺少权限或找不到对象错误

Spring-Boot 仅在一个配置文件中执行 data.sql

Spring Boot使用嵌入式容器,那怎么配置自定义Filter呢

是否可以在 Spring Boot 中运行两个使用 spring.jpa.generate-ddl 填充的嵌入式数据库?