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

Spring Boot+Maven+Spock配置Testcontainers PostgreSQL报错求助

Spring Boot + Testcontainers + Spock + PostgreSQL 集成测试配置问题解决

问题背景

我正在为Spring Boot应用配置Testcontainers集成测试,用PostgreSQL当数据库、Spock编写测试用例、Maven作为构建工具。翻了多篇博客但配置方式五花八门,自己编写测试类后运行时出现ApplicationContext加载失败的错误(Docker已正常运行),怀疑是依赖版本不匹配导致的。

现有代码与配置

测试类代码

@SpringBootTest
@Testcontainers
class MyIntegrationSpec extends Specification {

    @Container
    static PostgreSQLContainer postgresContainer = new PostgreSQLContainer<>("postgres:14-alpine")
            .withDatabaseName("testdb")
            .withUsername("testuser")
            .withPassword("testpass")

    @DynamicPropertySource
    static void configureProperties(DynamicPropertyRegistry registry) {
        registry.add("spring.datasource.url", postgresContainer::getJdbcUrl)
        registry.add("spring.datasource.username", postgresContainer::getUsername)
        registry.add("spring.datasource.password", postgresContainer::getPassword)
    }

    def "test database connection"() {
        expect:
        postgresContainer.isRunning()
    }
}

报错信息

org.springframework.context.ApplicationContextException: Unable to start web server; nested exception is org.springframework.boot.web.server.WebServerException: Unable to start embedded Tomcat
Caused by: org.springframework.boot.web.server.WebServerException: Unable to start embedded Tomcat
Caused by: org.apache.catalina.LifecycleException: Failed to start component [StandardServer[-1]]
// 省略后续栈信息,核心问题大概率为依赖冲突或缺失

Maven pom.xml 核心配置

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
        <groupId>org.postgresql</groupId>
        <artifactId>postgresql</artifactId>
        <scope>runtime</scope>
    </dependency>
    <!-- 测试依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.spockframework</groupId>
        <artifactId>spock-core</artifactId>
        <version>2.3-groovy-4.0</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.spockframework</groupId>
        <artifactId>spock-spring</artifactId>
        <version>2.3-groovy-4.0</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.testcontainers</groupId>
        <artifactId>postgresql</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.testcontainers</groupId>
        <artifactId>spock</artifactId>
        <version>1.19.3</version>
        <scope>test</scope>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
        <plugin>
            <groupId>org.codehaus.gmavenplus</groupId>
            <artifactId>gmavenplus-plugin</artifactId>
            <version>1.13.1</version>
            <executions>
                <execution>
                    <goals>
                        <goal>compile</goal>
                        <goal>testCompile</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <groovyVersion>4.0.15</groovyVersion>
            </configuration>
        </plugin>
    </plugins>
</build>

解决步骤

1. 统一Testcontainers版本

Testcontainers的所有模块(postgres、spock等)必须使用完全相同的版本,否则会出现类冲突。建议用BOM统一管理版本:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.testcontainers</groupId>
            <artifactId>testcontainers-bom</artifactId>
            <version>1.19.3</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

之后删掉pom中Testcontainers依赖的版本号,让BOM自动管理:

<dependency>
    <groupId>org.testcontainers</groupId>
    <artifactId>postgresql</artifactId>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.testcontainers</groupId>
    <artifactId>spock</artifactId>
    <scope>test</scope>
</dependency>

2. 对齐Spock、Groovy、Spring Boot版本

  • Spock 2.3要求搭配Groovy 4.0+,如果使用Spring Boot 3.x,必须配置JDK 17+;如果是Spring Boot 2.7.x,Spock使用2.2版本即可。
  • 确保spock-core和spock-spring版本一致,且与Groovy版本匹配。

3. 修正测试类注解与配置

  • @Testcontainers注解要使用org.testcontainers.spock.Testcontainers(Spock专用注解),不要使用Spring Boot的同名注解。
  • PostgreSQLContainer建议指定具体镜像版本(比如postgres:15-alpine),避免拉取最新镜像带来的兼容性问题。
  • 动态属性配置中添加驱动类名,确保Spring能正确识别:
@DynamicPropertySource
static void setupDatabaseProperties(DynamicPropertyRegistry registry) {
    registry.add("spring.datasource.url", postgresContainer::getJdbcUrl)
    registry.add("spring.datasource.username", postgresContainer::getUsername)
    registry.add("spring.datasource.password", postgresContainer::getPassword)
    registry.add("spring.datasource.driver-class-name", postgresContainer::getDriverClassName)
}

4. 检查Maven Groovy插件配置

gmavenplus-plugin的Groovy版本要和项目依赖的Groovy版本完全一致,确保测试代码能正常编译。

5. 定位根异常

如果仍报错,直接查看栈信息的最底层异常:

  • 若为ClassNotFoundException,检查依赖的scope是否为test(确保测试类能访问到),是否漏引依赖。
  • 若为数据库连接失败,确认容器的用户名、密码、数据库名与动态注入的属性一致,容器是否正常启动。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 07:19:53