SpringBoot接口测试出现Connection refused错误,请求排查原因
问题排查:Spring Boot测试连接localhost:8080被拒绝
问题描述
测试类代码:
@ExtendWith(SpringExtension.class) @ContextConfiguration(classes = {ApiController.class,TableService.class, CommonService.class}, loader = AnnotationConfigContextLoader.class) @TestPropertySource(locations = {"classpath:properties/test/application-test.properties"}) @ActiveProfiles(profiles = "test") @SpringBootTest(webEnvironment = WebEnvironment.DEFINED_PORT) public class ApiControllerTest { @Autowired private TestRestTemplate testRestTemplate; @Test public void successTypeHttp200Ok() throws JsonParseException, JsonMappingException, IOException { ResponseEntity<String> response = testRestTemplate. getForEntity("/v1/apc?name=test", String.class); } }
运行时抛出异常:
org.springframework.web.client.ResourceAccessException: I/O error on GET request for "http://localhost:8080/v1/apc": Connect to localhost:8080 [localhost/127.0.0.1, localhost/0:0:0:0:0:0:0:1] failed: Connection refused: connect; nested exception is org.apache.http.conn.HttpHostConnectException: Connect to localhost:8080 [localhost/127.0.0.1, localhost/0:0:0:0:0:0:0:1] failed: Connection refused: connect at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:785) ... Caused by: java.net.ConnectException: Connection refused: connect ...
排查方向及解决方案
1. 注解冲突导致Web服务器未启动
你同时使用了@ContextConfiguration和@SpringBootTest,@SpringBootTest本身已经负责加载Spring Boot应用上下文,手动指定@ContextConfiguration(classes = ...)会覆盖默认的上下文加载逻辑,只加载你指定的几个类,没有加载Spring Boot的Web自动配置类,导致内嵌Tomcat服务器根本没启动,自然连不上8080端口。
解决方法:去掉@ContextConfiguration注解,让@SpringBootTest自动扫描加载整个应用的上下文(包括Web相关配置):
@ExtendWith(SpringExtension.class) @TestPropertySource(locations = {"classpath:properties/test/application-test.properties"}) @ActiveProfiles(profiles = "test") @SpringBootTest(webEnvironment = WebEnvironment.DEFINED_PORT) public class ApiControllerTest { // 原有代码不变 }
如果必须指定特定类,应该用@SpringBootTest(classes = YourApplication.class)(传入你的主启动类),而不是单独用@ContextConfiguration。
2. WebEnvironment配置与端口不匹配
- 你用了
WebEnvironment.DEFINED_PORT,意味着会使用配置文件中server.port的值。检查application-test.properties里是否设置了server.port=8080,如果没设置,默认是8080,但如果上下文没加载Web配置,这个设置也不会生效。 - 更稳妥的方式是使用
WebEnvironment.RANDOM_PORT,让Spring Boot随机分配端口,TestRestTemplate会自动适配这个端口,不需要手动指定localhost:8080:
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) public class ApiControllerTest { @Autowired private TestRestTemplate testRestTemplate; @Test public void successTypeHttp200Ok() throws IOException { ResponseEntity<String> response = testRestTemplate.getForEntity("/v1/apc?name=test", String.class); } }
3. 依赖缺失
检查pom.xml(或build.gradle)是否引入了spring-boot-starter-web和spring-boot-starter-test依赖:
- Maven:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency>
- Gradle:
implementation 'org.springframework.boot:spring-boot-starter-web' testImplementation 'org.springframework.boot:spring-boot-starter-test'
缺少spring-boot-starter-web的话,Spring Boot不会启动内嵌Web服务器。
4. TestRestTemplate配置问题
如果以上都没问题,尝试手动配置TestRestTemplate并指定正确的端口,比如通过@LocalServerPort获取实际启动的端口:
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) public class ApiControllerTest { @LocalServerPort private int port; private TestRestTemplate testRestTemplate; @BeforeEach void setUp() { testRestTemplate = new TestRestTemplate(); testRestTemplate.getRestTemplate().setUriTemplateHandler(new DefaultUriBuilderFactory("http://localhost:" + port)); } @Test public void successTypeHttp200Ok() throws IOException { ResponseEntity<String> response = testRestTemplate.getForEntity("/v1/apc?name=test", String.class); } }
内容的提问来源于stack exchange,提问作者Vinod
相关产品推荐
相关产品推荐

