Spring Boot中RestTemplate跨服务请求测试编写及URI报错解决
RestTemplate Mock测试异常修复方案
异常根因
你遇到的java.lang.IllegalArgumentException: URI is required异常本质是Mockito打桩未命中,执行了真实RestTemplate的方法逻辑触发的,具体有三个错误点:
- Mock初始化错误:被
@Mock、@InjectMocks注解标注的对象不需要手动实例化,且未启用Mockito注解支持,导致Mock代理对象未生效 - 重载匹配错误:
postForEntity存在多个重载方法,直接写Mockito.any()没有指定匹配类型,无法正确匹配你业务代码中调用的重载,打桩规则失效 - 参数匹配失败:打桩时第二个参数直接传入实时生成的请求对象,若业务代码中生成的请求对象和该对象不满足
equals匹配规则,也会导致打桩未命中
修复方案
1. 修正测试类Mock初始化规则
启用Mockito注解支持,移除Mock对象的手动实例化逻辑:
- Junit4 增加
@RunWith(MockitoJUnitRunner.class)注解 - Junit5 增加
@ExtendWith(MockitoExtension.class)注解
2. 修正打桩匹配规则
明确指定每个参数的匹配器:
- 第一个URI参数:如果业务代码传的是字符串URI就用
anyString(),如果是URI类型对象就用any(URI.class),明确匹配重载 - 第二个请求体参数:如果需要精确匹配请求体就用
eq()包装你构造的预期请求对象,不需要精确匹配直接用any() - 第三个响应类型参数:用
eq()包装ChargeResponse.class
注意:Mockito规则要求只要有一个参数使用了匹配器,所有参数都必须使用匹配器,字面量值必须用eq()包装
完整可运行测试代码
// Junit5 版本注解,Junit4换成@RunWith(MockitoJUnitRunner.class) @ExtendWith(MockitoExtension.class) class ServiceTest { @Mock private RestTemplate restTemplate; @InjectMocks private RConsumerService refundConsumerService; @Test public void sendRequestToBillingService(){ // 构造模拟响应 ChargeResponse chargeResponse = new ChargeResponse(); chargeResponse.setInstanceKey("testInstanceKey"); // 构造入参 KafkaMessage kafkaMessage = new KafkaMessage(); kafkaMessage.setApplication_id(1L); kafkaMessage.setCompany_id(1111); TransactionRequestContext reqContext = refundConsumerService.createTxnRequestContext(kafkaMessage); // 构造预期请求体 ChargeRequest expectedChargeRequest = refundConsumerService.buildChargeRequest(reqContext); // 修正后的打桩逻辑,假设第一个参数是字符串类型URI Mockito.when(restTemplate.postForEntity( anyString(), eq(expectedChargeRequest), eq(ChargeResponse.class) )).thenReturn(new ResponseEntity<>(chargeResponse, HttpStatus.OK)); // 不需要精确匹配请求体可以用这个写法,适配性更高 // Mockito.when(restTemplate.postForEntity(anyString(), any(), eq(ChargeResponse.class))) // .thenReturn(new ResponseEntity<>(chargeResponse, HttpStatus.OK)); // 执行测试方法 refundConsumerService.refund(kafkaMessage); // 结果校验 assertEquals(chargeResponse.getInstanceKey(), "testInstanceKey"); } }
内容的提问来源于stack exchange,提问作者Sasha
相关产品推荐
相关产品推荐

