Spring Boot 3中RestTemplate单元测试依赖注入失败解决方法
解决Spring Boot测试中RestTemplate依赖注入失败问题
问题根源
你的测试类通过@SpringBootTest(classes = PosteDeliveryClientImpl.class)仅指定加载服务类,导致RestTemplateConfig配置类未被Spring容器扫描到,因此RestTemplate bean无法创建;同时你的配置类继承RestTemplate属于冗余操作,可能引发不必要的冲突。
解决方案
1. 先修复RestTemplate配置类
删除多余的继承关系,且Spring Boot已自动提供RestTemplateBuilder bean,无需手动定义:
@Configuration public class RestTemplateConfig { @Bean public RestTemplate restTemplate(RestTemplateBuilder builder) { return builder.build(); } }
2. 方案一:让测试类加载配置类
修改测试类的@SpringBootTest注解,同时指定服务类和配置类,确保Spring容器能扫描到RestTemplate bean:
@ExtendWith(SpringExtension.class) @SpringBootTest(classes = {PosteDeliveryClientImpl.class, RestTemplateConfig.class}) public class DeliveryBusinessClientTests { @Autowired private PosteDeliveryClientImpl posteDeliveryClient; @Test public void login() { var loginResponse = posteDeliveryClient.login(); assertEquals("Bearer", loginResponse.getToken_type()); } }
3. 方案二:使用MockBean隔离外部依赖(推荐单元测试使用)
单元测试不应依赖真实外部接口,通过@MockBean模拟RestTemplate的行为,完全隔离外部调用:
@ExtendWith(SpringExtension.class) @SpringBootTest(classes = PosteDeliveryClientImpl.class) public class DeliveryBusinessClientTests { @Autowired private PosteDeliveryClientImpl posteDeliveryClient; @MockBean private RestTemplate restTemplate; @Test public void login() { // 构造模拟响应 LoginResponse mockLoginResponse = new LoginResponse(); mockLoginResponse.setToken_type("Bearer"); ResponseEntity<LoginResponse> mockResponse = new ResponseEntity<>(mockLoginResponse, HttpStatus.OK); // 模拟RestTemplate的postForEntity方法行为 when(restTemplate.postForEntity( eq(PosteDeliveryClientImpl.ROOT_URI), any(LoginRequest.class), eq(LoginResponse.class) )).thenReturn(mockResponse); // 执行测试 var loginResponse = posteDeliveryClient.login(); assertEquals("Bearer", loginResponse.getToken_type()); } }
这种方式无需启动完整的HTTP客户端,测试速度更快且不依赖外部服务可用性,更符合单元测试的隔离原则。
内容的提问来源于stack exchange,提问作者PifTheWolf
相关产品推荐
相关产品推荐

