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.
相关产品推荐
相关产品推荐

