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

如何在JUnit测试代码中向测试容器启动的数据库插入数据

JUnit测试前插入Postgres测试数据的实现方案

针对你用Docker Compose配置的动态端口Postgres容器,下面是几种实用的实现方式:

1. 用Testcontainers管理容器+JDBC直接插入数据

因为容器用了动态端口,硬编码端口会导致连接失败,Testcontainers可以帮你自动启动Docker Compose服务并获取实际映射端口。

第一步:添加依赖(Maven为例)

<!-- Testcontainers核心 + Docker Compose支持 -->
<dependency>
    <groupId>org.testcontainers</groupId>
    <artifactId>junit-jupiter</artifactId>
    <version>1.19.3</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.testcontainers</groupId>
    <artifactId>docker-compose</artifactId>
    <version>1.19.3</version>
    <scope>test</scope>
</dependency>
<!-- Postgres JDBC驱动 -->
<dependency>
    <groupId>org.postgresql</groupId>
    <artifactId>postgresql</artifactId>
    <version>42.6.0</version>
    <scope>test</scope>
</dependency>

第二步:编写JUnit测试类

import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.testcontainers.containers.DockerComposeContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.io.File;

@Testcontainers
public class FunctionalTestDemo {

    // 加载你的docker-compose.yml文件
    @Container
    private static final DockerComposeContainer<?> composeContainer =
            new DockerComposeContainer<>(new File("docker-compose.yml"))
                    .withExposedService("postgres", 5432);

    private static String jdbcUrl;
    private static final String DB_USER = "username";
    private static final String DB_PASSWORD = "password";

    @BeforeAll
    static void initContainerConnection() {
        // 获取Postgres容器的实际对外端口
        Integer mappedPort = composeContainer.getServicePort("postgres", 5432);
        jdbcUrl = String.format("jdbc:postgresql://localhost:%d/myTestingDB", mappedPort);
    }

    @BeforeEach
    void insertTestRecords() throws SQLException {
        // 每次测试前插入测试数据,确保数据隔离
        try (Connection conn = DriverManager.getConnection(jdbcUrl, DB_USER, DB_PASSWORD)) {
            // 示例:插入user表数据,ON CONFLICT避免重复插入
            String insertSql = "INSERT INTO users (id, name, email) VALUES (?, ?, ?) ON CONFLICT DO NOTHING";
            try (PreparedStatement stmt = conn.prepareStatement(insertSql)) {
                stmt.setInt(1, 1);
                stmt.setString(2, "测试用户");
                stmt.setString(3, "test@demo.com");
                stmt.executeUpdate();
            }
            // 可添加更多插入逻辑
        }
    }

    @Test
    void testBusinessLogic() {
        // 这里编写你的功能测试代码,此时数据库已预加载测试数据
    }
}

2. Spring Boot项目简化方案

如果是Spring Boot项目,结合@Sql注解可以直接执行SQL脚本,无需手动写JDBC代码:

测试类示例

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.jdbc.Sql;
import org.testcontainers.containers.PostgresContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;

@Testcontainers
@SpringBootTest
public class SpringFunctionalTest {

    // 直接启动Postgres容器(替代Docker Compose,也可以用Docker Compose方式)
    @Container
    static PostgresContainer<?> postgresContainer = new PostgresContainer<>("my-proxy.jfrog.io/postgres:12")
            .withDatabaseName("myTestingDB")
            .withUsername("username")
            .withPassword("password");

    // 测试前自动执行classpath下的test-data.sql脚本
    @Sql("/test-data.sql")
    @Test
    void testWithPreloadedData() {
        // 编写功能测试逻辑
    }
}

对应的SQL脚本(src/test/resources/test-data.sql)

INSERT INTO users (id, name, email) VALUES (1, '测试用户', 'test@demo.com') ON CONFLICT DO NOTHING;
-- 可添加更多插入语句

关键注意事项

  • 动态端口处理:Testcontainers自动管理端口映射,通过getServicePort获取实际端口,避免硬编码导致的连接失败
  • 数据隔离:用@BeforeEach确保每次测试前数据一致,也可以在@AfterEach中执行清理SQL,或者开启事务回滚(Spring项目可用@Transactional)
  • 私有镜像认证:如果你的JFrog镜像需要认证,确保本地Docker已配置好镜像仓库凭证(在~/.docker/config.json中添加认证信息)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 17:20:41