使用RestTemplate时出现PotentialStubbingProblem存根参数不匹配问题
RestTemplate exchange()方法Mockito测试存根参数不匹配问题
我在应用中使用RestTemplate的exchange()方法调用外部API,编写JUnit和Mockito测试用例时遇到了存根参数不匹配异常,尝试过lenient()方法但问题仍未解决。
业务代码
@Service public class ApiService { @Autowired private RestTemplate restTemplate; @Value("{url}") private String url; public TrackResponse getTpiValue(TrackRequest trackRequest){ TrackResponse trackResponse = null; HttpHeaders headers = new HttpHeaders(); HttpEntity<TrackRequest> entity = new HttpEntity<TrackRequest>(trackRequest, headers); ResponseEntity<TrackResponse> response = restTemplate.exchange(url, HttpMethod.Post, entity, TrackResponse.class); if(response.getStatusCode == HttpStatus.ok){ trackResponse = response.getBody(); } return trackResponse; } }
测试用例代码
@TestInstance(Lifecycle.PER_CLASS) @ExtendWith(MocikotExtension.class) public class ApiServiceTest { @Mock private RestTemplate restTemplate; @InjectMocks private ApiService apiService; public void getTpiValueTest(){ TrackRequest trackRequest = new TrackRequest(); trackRequest.setId("UTHL10"); TrackResponse trackResponse = new TrackResponse(); trackResponse.setTrackId("QWEDRTHFDS"); ResponseEntity<TrackResponse> response = new ResponseEntity<>(trackResponse, HttpStatus.ok); when(restTemplate.exchange(eq(null), eq(HttpMethod.Post), any(HttpEntity.class), eq(TrackResponse.class))).thenReturn(response); TrackResponse finalResponse = apiService.getTpiValue(trackRequest); assetEquals(response.getbody(), finalResponse.getTrackId()); } }
报错信息
org.mockito.exceptions.misusing.PotentialStubbingProblem: Strict stubbing argument mismatch. Please check: - this invocation of 'exchange' method: restTemplate.exchange( null, POST, <com.application.track.TrackRequest@3c486eb1,[]>, class com.application.track.TrackResponse ); -> at com.application.track.ApiService.getTpiValue(ApiService.java:18) - has following stubbing(s) with different arguments: 1. restTemplate.exchange( null, null, null, null ); -> at com.application.track.ApiServiceTest.getTpiValueTest(ApiServiceTest.java:21)
问题分析与修复方案
1. 测试类注解拼写错误
@ExtendWith(MocikotExtension.class) 中的 MocikotExtension 是拼写错误,正确应为 MockitoExtension。这个错误会导致Mockito无法正确初始化Mock对象,是参数匹配异常的核心原因之一。
2. 静态导入缺失
测试用例中使用了eq()、any()等匹配器,但如果没有静态导入org.mockito.ArgumentMatchers.*,Mockito会将这些方法调用视为普通对象而非匹配器,导致存根参数匹配失效,出现null参数的存根记录。
3. 测试方法缺少@Test注解
当前测试方法getTpiValueTest()没有添加@Test注解,JUnit不会执行该测试方法,修正后才能触发测试逻辑。
4. 断言逻辑错误
原断言assetEquals(response.getbody(), finalResponse.getTrackId())存在两处错误:
assetEquals应为assertEqualsresponse.getbody()是TrackResponse对象,finalResponse.getTrackId()是字符串,类型不匹配,应改为比较两者的trackId属性
5. 业务代码小问题(可选修复)
业务代码中@Value("{url}")缺少$符号,正确应为@Value("${url}");HttpMethod.Post应为HttpMethod.POST,response.getStatusCode == HttpStatus.ok应为response.getStatusCode() == HttpStatus.OK(注意方法调用和大写常量)。
修复后的测试用例代码
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestInstance; import org.junit.jupiter.api.TestInstance.Lifecycle; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.http.HttpEntity; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.when; @TestInstance(Lifecycle.PER_CLASS) @ExtendWith(MockitoExtension.class) public class ApiServiceTest { @Mock private RestTemplate restTemplate; @InjectMocks private ApiService apiService; @Test public void getTpiValueTest() { // 准备测试数据 TrackRequest trackRequest = new TrackRequest(); trackRequest.setId("UTHL10"); TrackResponse trackResponse = new TrackResponse(); trackResponse.setTrackId("QWEDRTHFDS"); ResponseEntity<TrackResponse> mockResponse = new ResponseEntity<>(trackResponse, HttpStatus.OK); // 正确存根RestTemplate的exchange方法 when(restTemplate.exchange( eq(null), // 对应业务代码中未注入的url eq(HttpMethod.POST), any(HttpEntity.class), eq(TrackResponse.class) )).thenReturn(mockResponse); // 执行测试方法 TrackResponse finalResponse = apiService.getTpiValue(trackRequest); // 断言结果 assertEquals(mockResponse.getBody().getTrackId(), finalResponse.getTrackId()); } }
内容的提问来源于stack exchange,提问作者Rahul
相关产品推荐
相关产品推荐

