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

Testcontainer无法加载类路径初始化脚本问题求助

Postgres Testcontainer初始化脚本加载失败问题

尝试启动Postgres Testcontainer并通过withInitScript(String)方法加载初始化脚本时,抛出以下错误:

org.testcontainers.ext.ScriptUtils$ScriptLoadException: Could not load classpath init script: /home/ilys/Programming/learn/testHibernate/app/src/test/resources/my_dump.sql. Resource not found.

尽管脚本文件实际存在,仍无法被加载。以下是相关信息及解决方案:


依赖配置

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter'
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation group: 'org.reflections', name: 'reflections', version: '0.10.2'
    implementation group: 'org.postgresql', name: 'postgresql', version: '42.6.0'
    compileOnly 'org.projectlombok:lombok:1.18.28'
    annotationProcessor 'org.projectlombok:lombok:1.18.28'

    developmentOnly 'org.springframework.boot:spring-boot-devtools'

    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    testImplementation 'org.springframework.boot:spring-boot-testcontainers'
    testImplementation 'org.testcontainers:junit-jupiter'
    testImplementation group: 'org.testcontainers', name: 'postgresql', version: '1.19.4'
}

Testcontainer初始化代码

@Container
static PostgreSQLContainer<?> postgres;

static {
    File dump = new File("src/test/resources/my_dump.sql");
    System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
    System.out.println("DUMP FILE ABS PATH: " + dump.getAbsolutePath());
    System.out.println("DUMP FILE EXISTS: " + dump.exists());

    postgres = new PostgreSQLContainer<>("postgres:15")
            .withUsername("postgres")
            .withPassword("pass")
            .withExposedPorts(5432)
            .withInitScript(dump.getAbsolutePath())
            .withDatabaseName("postgres");
}

运行输出

> Task :common:compileJava UP-TO-DATE
> Task :app:compileJava
> Task :app:processResources UP-TO-DATE
> Task :app:classes
> Task :app:compileTestJava
> Task :app:processTestResources UP-TO-DATE
> Task :app:testClasses
> Task :common:processResources NO-SOURCE
> Task :common:classes UP-TO-DATE
> Task :common:jar UP-TO-DATE
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
DUMP FILE ABS PATH: /home/ilys/Programming/learn/testHibernate/app/src/test/resources/my_dump.sql
DUMP FILE EXISTS: true
11:50:15.079 [Test worker] INFO org.testcontainers.utility.ImageNameSubstitutor -- Image name substitution will be performed by: DefaultImageNameSubstitutor (composite of 'ConfigurationFileImageNameSubstitutor' and 'PrefixingImageNameSubstitutor')
11:50:15.173 [Test worker] INFO org.testcontainers.dockerclient.DockerClientProviderStrategy -- Loaded org.testcontainers.dockerclient.UnixSocketClientProviderStrategy from ~/.testcontainers.properties, will try it first
11:50:15.267 [Test worker] INFO org.testcontainers.dockerclient.DockerClientProviderStrategy -- Found Docker environment with local Unix socket (unix:///var/run/docker.sock)
11:50:15.268 [Test worker] INFO org.testcontainers.DockerClientFactory -- Docker host IP address is localhost
11:50:15.276 [Test worker] INFO org.testcontainers.DockerClientFactory -- Connected to docker: 
  Server Version: 24.0.7
  API Version: 1.43
  Operating System: Manjaro Linux
  Total Memory: 64031 MB
11:50:15.291 [Test worker] INFO tc.testcontainers/ryuk:0.5.1 -- Creating container for image: testcontainers/ryuk:0.5.1
11:50:15.376 [Test worker] INFO tc.testcontainers/ryuk:0.5.1 -- Container testcontainers/ryuk:0.5.1 is starting: db2b087f633ba2310499f02692f762974c07ff594efbc5ae126d5eac8db9f9a4
11:50:15.629 [Test worker] INFO tc.testcontainers/ryuk:0.5.1 -- Container testcontainers/ryuk:0.5.1 started in PT0.349619688S
11:50:15.632 [Test worker] INFO org.testcontainers.utility.RyukResourceReaper -- Ryuk started - will monitor and terminate Testcontainers containers on JVM exit
11:50:15.632 [Test worker] INFO org.testcontainers.DockerClientFactory -- Checking the system...
11:50:15.632 [Test worker] INFO org.testcontainers.DockerClientFactory -- ✔︎ Docker server version should be at least 1.6.0
11:50:15.633 [Test worker] INFO tc.postgres:15 -- Creating container for image: postgres:15
11:50:15.677 [Test worker] INFO tc.postgres:15 -- Container postgres:15 is starting: c7d3772fddcddf6d7aaaa60e4170edf95dc609b353317de1d291a2575bd25a8c
11:50:16.558 [Test worker] INFO tc.postgres:15 -- Container postgres:15 started in PT0.925549685S
11:50:16.559 [Test worker] INFO tc.postgres:15 -- Container is started (JDBC URL: jdbc:postgresql://localhost:32797/postgres?loggerLevel=OFF)
11:50:16.560 [Test worker] WARN org.testcontainers.ext.ScriptUtils -- Could not load classpath init script: /home/ilys/Programming/learn/testHibernate/app/src/test/resources/my_dump.sql
11:50:16.560 [Test worker] ERROR tc.postgres:15 -- Could not start container
org.testcontainers.ext.ScriptUtils$ScriptLoadException: Could not load classpath init script: /home/ilys/Programming/learn/testHibernate/app/src/test/resources/my_dump.sql. Resource not found.

初始化脚本内容

CREATE TABLE IF NOT EXISTS public.first_table
(
    id bigserial not null,
    val text not null,
    constraint pk_setting_value primary key (id)
);

INSERT INTO first_table(val) values ('1234_test');
INSERT INTO first_table(val) values ('2345_test');
INSERT INTO first_table(val) values ('3456_test');
INSERT INTO first_table(val) values ('4567_test');

解决方案

核心原因

withInitScript(String)方法的参数被Testcontainers当作类路径资源路径处理,而非本地文件系统的绝对路径。即使文件存在,也会从类路径中查找而非本地路径。

方法1:使用类路径相对路径

由于脚本已放在src/test/resources目录下(该目录会被加入类路径),直接传入相对路径即可:

postgres = new PostgreSQLContainer<>("postgres:15")
        .withUsername("postgres")
        .withPassword("pass")
        .withExposedPorts(5432)
        .withInitScript("my_dump.sql") // 类路径相对路径
        .withDatabaseName("postgres");

方法2:复制本地文件到容器执行

如果必须使用本地绝对路径,改用withCopyFileToContainer()将脚本复制到Postgres容器的初始化目录,容器启动时会自动执行该目录下的SQL:

postgres = new PostgreSQLContainer<>("postgres:15")
        .withUsername("postgres")
        .withPassword("pass")
        .withExposedPorts(5432)
        .withDatabaseName("postgres")
        .withCopyFileToContainer(MountableFile.forHostPath(dump.getAbsolutePath()), "/docker-entrypoint-initdb.d/my_dump.sql");

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 07:37:03