Testcontainers是一个Java库,允许在JUnit测试中轻松集成Docker容器。在一个容器化的世界里,用嵌入式数据库和服务使测试配置复杂化是没有意义的。相反,使用在Docker中运行你的服务,让Testcontainers为你管理这些。
在这篇博文中,你将学习如何配置Testcontainers,在Spring Boot 2集成测试中运行PostgreSQL、MySQL和MariaDB。
这篇博文包括。
- Testcontainers的配置(通过JDBC URL Scheme),用于Spring Boot 2测试的PostgreSQL、MySQL和MariaDB。
- Testcontainers在
@DataJpaTest
目录
依赖关系
为了使用Testcontainers,在pom.xml
(假设是基于Maven的项目)中添加以下依赖项。
<properties>
<org.testcontainers.version>1.12.5</org.testcontainers.version>
</properties>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers</artifactId>
<version>${org.testcontainers.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>DATABASE</artifactId>
<version>${org.testcontainers.version}</version>
<scope>test</scope>
</dependency>
复制代码
其中DATABASE
是postgresql
,mysql
,mariadb
中的一个。
注意:Testcontainers提供了JUnit 5 (Jupiter)插件,但在本文介绍的场景中不需要该插件。
测试数据源配置
为Spring Boot测试配置Testcontainers的步骤。
- 将驱动程序设置为
org.testcontainers.jdbc.ContainerDatabaseDriver
,这是一个Testcontainers JDBC代理驱动程序。这个驱动使将负责在数据源初始化时启动所需的Docker容器。 - 将方言明确设置为你的数据库的方言实现,否则你在启动应用程序时就会出现异常。当你在你的应用程序中使用JPA(通过Spring Data JPA)时,这一步是必须的
- 将JDBC URL设置为
jdbc:tc:<database-image>:<version>:///
,以便Testcontainers知道要使用哪个数据库镜像。
PostgreSQL的配置。
完整的配置。
spring.datasource.driver-class-name=org.testcontainers.jdbc.ContainerDatabaseDriver
spring.datasource.url=jdbc:tc:postgresql:9.6:///
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQL9Dialect
复制代码
MySQL的配置。
spring.datasource.driver-class-name=org.testcontainers.jdbc.ContainerDatabaseDriver
spring.datasource.url=jdbc:tc:mysql:8:///
spring.jpa.database-platform=org.hibernate.dialect.MySQL8Dialect
复制代码
MariaDB的配置。
spring.datasource.driver-class-name=org.testcontainers.jdbc.ContainerDatabaseDriver
spring.datasource.url=jdbc:tc:mariadb:10.3:///
spring.jpa.database-platform=org.hibernate.dialect.MariaDB103Dialect
复制代码
更多关于数据库配置的信息请看这里的官方文档: https://www.testcontainers.org/modules/databases/
用Testcontainers初始化测试数据库
你可以用Testcontainers加载的脚本来初始化数据库。该文件可以直接从classpath加载,也可以从任何位置加载。唯一要做的就是改变JDBC的URL。
spring.datasource.url=jdbc:tc:postgresql:9.6:///?TC_INITSCRIPT=file:src/main/resources/init_db.sql
复制代码
或
spring.datasource.url=jdbc:tc:postgresql:9.6:///?TC_INITSCRIPT=classpath:init_db.sql
复制代码
@DataJpaTest
为了在@DataJpaTest
中使用TC,你需要确保使用应用程序定义的(自动配置的)数据源。你可以通过用@AutoConfigureTestDatabase
注释你的测试来轻松做到这一点,如下所示。
@DataJpaTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
public class OwnerRepositoryTests {
@Autowired
private OwnerRepository ownerRepository;
@Test
void findAllReturnsJohnDoe() { // as defined in tc-initscript.sql
var owners = ownerRepository.findAll();
assertThat(owners.size()).isOne();
assertThat(owners.get(0).getFirstName()).isEqualTo("John");
assertThat(owners.get(0).getLastName()).isEqualTo("Doe");
}
}
复制代码
@SpringBootTest
@SpringBootTest
将使用应用程序定义的数据源,所以不需要额外的修改。
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureMockMvc
public class OwnerResourceTests {
@Autowired
WebApplicationContext wac;
@Test
void findAllReturnsJohnDoe() throws Exception {
given()
.webAppContextSetup(wac)
.when()
.get("/owners")
.then()
.status(HttpStatus.OK)
.body(
"_embedded.owners.firstName", containsInAnyOrder("John"),
"_embedded.owners.lastName", containsInAnyOrder("Doe")
);
}
}
复制代码
总结
你刚刚学会了在Spring Boot集成测试中用Testcontainers配置PostgreSQL、MySQL和MariaDB的最简单方法。这个解决方案很适合于相当简单的设置。如果你需要对Docker镜像有更多的控制,请参考Testcontainers官方文档。
源代码
本文的源代码可以在Github上找到:https://github.com/kolorobot/spring-boot-tc