likes
comments
collection
share

SpringBoot单元测试实践——数据隔离篇(TestContainers)

作者站长头像
站长
· 阅读数 73

前言

依赖配置

首先它的功能是拉起一个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
评论
请登录