Spring Boot 测试容器支持中文文档

本文为官方文档直译版本。原文链接

引言

除了在集成测试中使用 Testcontainers 外,在开发过程中也可以使用它们。接下来的章节将详细介绍这一点。

在开发时使用测试容器

这种方法允许开发人员为应用程序所依赖的服务快速启动容器,无需手动配置数据库服务器等。以这种方式使用 Testcontainers 所提供的功能与 Docker Compose 类似,只是容器配置使用的是 Java 而不是 YAML。
要在开发时使用 Testcontainers,您需要使用 "test "类路径而不是 "main "来启动应用程序。这将允许您访问所有已声明的测试依赖项,并为您提供一个编写测试配置的自然位置。
要创建应用程序的测试启动版本,应在 src/test 目录下创建一个 “Application” 类。例如,如果您的主应用程序在 src/main/java/com/example/MyApplication.java 中,则应创建 src/test/java/com/example/TestMyApplication.java
TestMyApplication 类可使用 SpringApplication.from(...) 方法启动真实应用程序:

import org.springframework.boot.SpringApplication;

public class TestMyApplication {

    public static void main(String[] args) {
        SpringApplication.from(MyApplication::main).run(args);
    }

}

您还需要定义要与应用程序一起启动的容器实例。为此,您需要确保已将 spring-boot-testcontainers 模块添加为测试依赖关系。添加完成后,您就可以创建一个 @TestConfiguration 类,为要启动的容器声明 @Bean 方法。
您还可以用 @ServiceConnection@Bean 方法进行注解,以创建 ConnectionDetails Bean。有关支持技术的详细信息,请参阅服务连接部分。
典型的 Testcontainers 配置如下所示:

import org.testcontainers.containers.Neo4jContainer;

import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.context.annotation.Bean;

@TestConfiguration(proxyBeanMethods = false)
public class MyContainersConfiguration {

    @Bean
    @ServiceConnection
    public Neo4jContainer<?> neo4jContainer() {
        return new Neo4jContainer<>("neo4j:5");
    }

}

容器 Bean 的生命周期由 Spring Boot 自动管理。容器将自动启动和停止。

您可以使用 spring.testcontainers.beans.startup 属性来更改容器的启动方式。默认情况下使用顺序启动,但如果希望并行启动多个容器,也可以选择并行启动。

定义好测试配置后,就可以使用 with(...) 方法将其附加到测试启动器:

import org.springframework.boot.SpringApplication;

public class TestMyApplication {

    public static void main(String[] args) {
        SpringApplication.from(MyApplication::main).with(MyContainersConfiguration.class).run(args);
    }
}

现在,您可以像启动普通 Java 主方法应用程序一样启动 TestMyApplication,以启动应用程序及其运行所需的容器。

您可以使用 Maven 任务 spring-boot:test-run 或 Gradle 任务 bootTestRun 从命令行执行此操作。

开发时贡献动态属性

如果您想在开发时从容器 @Bean 方法中贡献动态属性,可以通过注入 DynamicPropertyRegistry 来实现。其工作方式与您可以在测试中使用的 @DynamicPropertySource 注解类似。它允许您添加在容器启动后可用的属性。
典型的配置如下:

import org.testcontainers.containers.MongoDBContainer;

import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.test.context.DynamicPropertyRegistry;

@TestConfiguration(proxyBeanMethods = false)
public class MyContainersConfiguration {

    @Bean
    public MongoDBContainer mongoDbContainer(DynamicPropertyRegistry properties) {
        MongoDBContainer container = new MongoDBContainer("mongo:5.0");
        properties.add("spring.data.mongodb.host", container::getHost);
        properties.add("spring.data.mongodb.port", container::getFirstMappedPort);
        return container;
    }

}

建议尽可能使用 @ServiceConnection,不过,对于尚未支持 @ServiceConnection 的技术来说,动态属性可能是一种有用的备用方法。

导入测试容器声明类

使用 Testcontainers 时的一种常见模式是将 Container 实例声明为静态字段。这些字段通常直接在测试类中定义。它们也可以在父类或测试实现的接口上声明。
例如,下面的 MyContainers 接口声明了 mongoneo4j 容器:

import org.testcontainers.containers.MongoDBContainer;
import org.testcontainers.containers.Neo4jContainer;
import org.testcontainers.junit.jupiter.Container;

import org.springframework.boot.testcontainers.service.connection.ServiceConnection;

public interface MyContainers {

    @Container
    @ServiceConnection
    MongoDBContainer mongoContainer = new MongoDBContainer("mongo:5.0");

    @Container
    @ServiceConnection
    Neo4jContainer<?> neo4jContainer = new Neo4jContainer<>("neo4j:5");

}

如果您已经有了以这种方式定义的容器,或者您只是喜欢这种风格,您可以导入这些声明类,而不是将容器定义为 @Bean 方法。为此,请在测试配置类中添加 @ImportTestcontainers 注解:

import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.boot.testcontainers.context.ImportTestcontainers;

@TestConfiguration(proxyBeanMethods = false)
@ImportTestcontainers(MyContainers.class)
public class MyContainersConfiguration {

}

如果您不打算使用服务连接功能,而是想使用 @DynamicPropertySource,请从容器字段中删除 @ServiceConnection 注解。您还可以在声明类中添加 @DynamicPropertySource 注解方法。

在开发时将 DevTools 与 Testcontainers 结合使用

使用 devtools 时,您可以用 @RestartScope 对 bean 和 bean 方法进行注解。当 devtools 重新启动应用程序时,这些 Bean 将不会被重新创建。这对 Testcontainer Container Bean 尤其有用,因为它们会在应用程序重启时保持状态。

import org.testcontainers.containers.MongoDBContainer;

import org.springframework.boot.devtools.restart.RestartScope;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.context.annotation.Bean;

@TestConfiguration(proxyBeanMethods = false)
public class MyContainersConfiguration {

    @Bean
    @RestartScope
    @ServiceConnection
    public MongoDBContainer mongoDbContainer() {
        return new MongoDBContainer("mongo:5.0");
    }

}

如果您使用 Gradle 并希望使用此功能,则需要将 spring-boot-devtools 依赖关系的配置从 "developmentOnly"更改为 “testImplementation”。如果默认作用域为 “developmentOnly”,BootTestRun 任务将无法捕获代码中的更改,因为 devtools 并未激活。

  • 22
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值