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

Spring Boot 2.7.1 JUnit5端点测试随机端口不生效问题

问题根因

核心问题出在你的Gradle配置里:你在configurations.implementation块中全局排除了spring-boot-starter-tomcat嵌入式Servlet容器依赖,又没有引入其他嵌入式Web容器(Jetty/Undertow),导致Spring Boot启动时识别不到Web环境,根本没有拉起真实的Servlet Web服务,所有异常都是这个问题连锁导致的:

  • 没有启动真实Web服务,SpringBootTest.WebEnvironment.RANDOM_PORT规则完全不生效,不会分配随机监听端口,@LocalServerPort自然找不到local.server.port对应的配置值,直接抛出占位符解析异常
  • 没有嵌入式容器支撑,哪怕手动配置server.port=0,也无法完成端口监听,直接抛出地址绑定错误
  • 自动注入的TestRestTemplate拿不到实际启动的服务端口,只能回退到默认的8080端口发起请求
修复方案

根据你的实际需求二选一即可:

方案1:使用默认Tomcat作为嵌入式容器

直接删除build.gradle里这段全局排除Tomcat的配置:

implementation {
    exclude module: 'spring-boot-starter-tomcat'
}

spring-boot-starter-web默认会传递引入Tomcat starter,删除排除规则后重新构建依赖,Spring Boot测试启动时会自动拉起嵌入式Tomcat,随机端口分配、TestRestTemplate自动装配、@LocalServerPort注入都会恢复正常。

方案2:替换Tomcat为其他嵌入式容器

如果你排除Tomcat是为了换用其他Web服务器,必须在依赖块中引入对应容器的官方starter,比如:

  • 用Undertow作为容器,添加依赖:
implementation 'org.springframework.boot:spring-boot-starter-undertow'
  • 用Jetty作为容器,添加依赖:
implementation 'org.springframework.boot:spring-boot-starter-jetty'

引入对应依赖后,Spring Boot就能自动识别可用的嵌入式Web容器,正常启动Web服务,测试相关的端口注入、请求逻辑都会正常工作。

验证方法

修复依赖后,可以在测试类里加一行端口打印快速确认配置生效:

@LocalServerPort
private int randomServerPort;

@Test
public void getOpenApiDocumentationShouldReturnOk() {
    // 控制台能打印出非8080的随机端口,就说明Web服务正常启动了
    System.out.println("测试服务启动端口:" + randomServerPort);
    assertThat(restTemplate.getForEntity("/api-docs", String.class).getStatusCode())
      .isEqualTo(HttpStatus.OK);
}

能正常打印随机端口、接口返回200状态码,就说明问题已经完全解决。

内容的提问来源于stack exchange,提问作者Gilberto T.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 05:12:17