You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Docker容器内运行Spring Boot测试,贴近真实环境验证服务?

方案1:将Spring Boot服务作为普通Docker容器运行测试(推荐,复杂度低,完全满足生产环境模拟需求)

前置配置

  • 先调整Gradle配置,确保测试执行前已构建好服务镜像:在build.gradle中添加test.dependsOn dockerBuild,保证每次跑测试用的是最新代码构建的镜像。
  • 所有依赖容器(PostgreSQL、Localstack)和服务容器需加入同一Docker网络,配置网络别名实现内部互通。

测试代码修改

你现有的测试类需要调整架构,去掉本地启动Spring Boot上下文的相关注解,改为启动容器化的服务,示例修改后的代码如下:

@Testcontainers
@TestMethodOrder(OrderAnnotation.class)
class MyApplicationTests {
    static DockerImageName localstackImage = DockerImageName.parse("localstack/localstack:0.11.3");
    private static final LocalStackContainer.Service[] TEST_SERVICES = {
            LocalStackContainer.Service.SECRETSMANAGER,
            LocalStackContainer.Service.SSM,
            LocalStackContainer.Service.EC2,
    };
    // 定义网络,所有容器加入该网络
    static Network testNetwork = Network.newNetwork();

    @Container
    static LocalStackContainer awsLocalStackContainers = new LocalStackContainer(localstackImage)
            .withServices(TEST_SERVICES)
            .withEnv("LOCALSTACK_HOSTNAME", "localstack")
            .withEnv("HOSTNAME", "localstack")
            .withNetwork(testNetwork)
            .withNetworkAliases("localstack"); // 网络别名,同网络内其他容器可通过该名称访问

    @Container
    public static PostgreSQLContainer<?> postgreSQL =
            new PostgreSQLContainer<>("postgres:13.1")
                    .withUsername("clusteradmin")
                    .withPassword("testPassword")
                    .withDatabaseName("public")
                    .withNetwork(testNetwork)
                    .withNetworkAliases("postgres"); // 数据库网络别名

    // 定义Spring Boot服务容器,镜像名替换为你Palantir插件构建的实际镜像名
    @Container
    static GenericContainer<?> appContainer = new GenericContainer<>("payouts-service:latest")
            .withNetwork(testNetwork)
            .withExposedPorts(8080) // 替换为你服务实际监听的端口
            .dependsOn(postgreSQL, awsLocalStackContainers) // 依赖容器启动后再启服务
            // 注入服务所需的所有配置,对应你原来的application-test.yml配置
            .withEnv("SPRING_PROFILES_ACTIVE", "test,jpa")
            .withEnv("SPRING_DATASOURCE_URL", "jdbc:postgresql://postgres:5432/public")
            .withEnv("SPRING_DATASOURCE_USERNAME", "clusteradmin")
            .withEnv("SPRING_DATASOURCE_PASSWORD", "testPassword")
            .withEnv("AWS_SECRETSMANAGER_ENDPOINT", "http://localstack:4566")
            .withEnv("AWS_SSM_ENDPOINT", "http://localstack:4566")
            .withEnv("AWS_REGION", awsLocalStackContainers.getRegion())
            .withEnv("aws.paramstore.enabled", "false")
            .withEnv("aws.secretsmanager.enabled", "false")
            // 你需要排除的Spring Cloud AWS自动配置也可以通过环境变量注入,或者直接写在测试配置文件里
            .withEnv("SPRING_AUTOCONFIGURE_EXCLUDE", "org.springframework.cloud.aws.autoconfigure.context.ContextInstanceDataAutoConfiguration,org.springframework.cloud.aws.autoconfigure.context.ContextStackAutoConfiguration,org.springframework.cloud.aws.autoconfigure.context.ContextRegionProviderAutoConfiguration");

    // 测试用例示例:通过映射端口访问容器内的服务
    @Test
    void testServiceHealth() {
        String baseUrl = "http://" + appContainer.getHost() + ":" + appContainer.getMappedPort(8080);
        RestTemplate restTemplate = new RestTemplate();
        String healthRes = restTemplate.getForObject(baseUrl + "/actuator/health", String.class);
        // 断言验证返回结果
        Assertions.assertNotNull(healthRes);
    }
}

注意事项

  • 你原来的PropertiesListener逻辑如果需要注入Localstack客户端,不需要再用反射注入,直接在Localstack容器启动后调用对应API往Secret Manager、SSM里写入测试数据即可,服务启动后会自动从Localstack读取。
  • 如果需要传递更多配置,直接通过withEnv方法注入环境变量即可,和生产环境容器运行的参数传递方式完全一致。
方案2:在Localstack EC2实例中运行服务测试(仅当需要验证EC2内运行逻辑时使用,复杂度较高)
  1. 服务镜像构建完成后,调用Localstack的EC2 API将镜像导入到Localstack的镜像仓库中
  2. 调用EC2 RunInstances接口启动实例,指定使用导入的服务镜像,配置实例安全组开放服务端口
  3. 通过Localstack的EC2公网IP映射访问服务,执行测试逻辑

该方案需要额外编写EC2操作的工具代码,常规测试不需要用到,方案1已经可以100%模拟生产容器运行环境。

内容的提问来源于stack exchange,提问作者MrkK

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 14:15:04