SpringBoot单元测试实践——数据隔离篇(TestContainers)
前言
依赖配置
首先它的功能是拉起一个Doker镜像,那我们的单元测试环境中必须要安装了Docker,这是前提。然后需要配置我们的maven依赖:
<!-- 这是截止至这篇文章时的最新版本 -->
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers</artifactId>
<version>1.18.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>mysql</artifactId>
<version>1.18.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>junit-jupiter</artifactId>
<version>1.18.3</version>
<scope>test</scope>
</dependency>
测试代码
配置完依赖之后,就可以开始写我们的单元测试代码了:
@Testcontainers
@SpringBootTest
public class ContainersTest {
/**
* 通过@Container注解标记这是一个container
*/
@Container
public MySQLContainer<?> mysqlContainer = new MySQLContainer<>(DockerImageName.parse("mysql:8.0-debian")).withExposedPorts(3306);
/**
* 覆盖数据库配置
*/
@DynamicPropertySource
public void dynamicProperties(DynamicPropertyRegistry registry) {
registry.add("spring.datasource.url", () -> mysqlContainer.getJdbcUrl());
registry.add("spring.datasource.driverClassName", () -> mysqlContainer.getDriverClassName());
registry.add("spring.datasource.username", () -> mysqlContainer.getUsername());
registry.add("spring.datasource.password", () -> mysqlContainer.getPassword());
}
/**
* 测试用例
*/
@Sql(
scripts = "create-data.sql",
config = @SqlConfig(transactionMode = ISOLATED)
)
@Test
public void testSaveOrUpdate() {
//do something db operation
}
}
经过这些配置之后,那我们每次运行单元测试,它都会拉起一个MySQL镜像,然后我们获取它的数据信息,替换掉原来的配置,并且初始化数据。就可以保证每次运行单元测试,都有一个干净的环境,并且不会受到其它外部因素的影响。
总结
上面介绍了如何使用TestContainers
来自动运行Docker镜像,从而保证数据的隔离,而且不仅仅是数据库,其它的包括Redis、Kafka等中间件,都可以通过这种方式进行隔离,这样就可以保证我们的单元测试完全是独立运行的,可以保证它的稳定性
与正确性
。但是它不是所有的场景都适用,首先需要有Docker环境
,其次拉起很多镜像的话,会对内存有要求
,而且单元测试的运行时间也会变得更长
。大家可以根据自己的实际情况来选择合适的数据隔离方案。
转载自:https://juejin.cn/post/7268191936660619316