Mock RestTemplate返回Null问题排查与修复求助
解决RestTemplate Mock返回null导致的NullPointerException问题
错误信息
Cannot invoke "org.springframework.http.ResponseEntity.getBody()" because "response" is null
java.lang.NullPointerException: Cannot invoke "org.springframework.http.ResponseEntity.getBody()" because "response" is null
测试类代码
class UtilsControllerTest { @Mock RestTemplate restTemplate=mock(RestTemplate.class); @Test void checkPermission() { boolean permitted = true; ResponseEntity<PermissionResponseModel> response = ResponseEntity.ok(new PermissionResponseModel(permitted)); when(restTemplate.postForEntity(any(String.class), any(Map.class), any(Class.class))) .thenReturn(response); UtilsController utilsController = new UtilsController(); assertTrue(utilsController.checkPermission("69696969", Task.MAKE_REQUEST, restTemplate)); verify(restTemplate, times(1)).postForEntity(any(), any(), any()); } }
UtilsController实现代码
public class UtilsController { private static final String authString = "Authorization"; /** * Checks if the user is authorised to do a certain task. * * @param token the identification token * @param task the task * @return true iff user is allowed, false otherwise */ public boolean checkPermission(String token, Task task, RestTemplate restTemplate) { HttpHeaders authHeaders = new HttpHeaders(); authHeaders.setContentType(MediaType.APPLICATION_JSON); authHeaders.set(authString, token); String url = "http://localhost:8081/permission"; PermissionRequestModel prm = new PermissionRequestModel(); prm.setTask(task); HttpEntity<PermissionResponseModel> entity = new HttpEntity(prm, authHeaders); ResponseEntity<PermissionResponseModel> response = restTemplate.postForEntity(url, entity, PermissionResponseModel.class); return response.getBody().isPermitted(); } }
问题原因
你的Mock配置参数和实际调用不匹配:测试中用any(Map.class)匹配请求体,但实际代码里传递的是HttpEntity对象,导致Mockito找不到对应的Stub,返回默认的null值。同时,测试类里@Mock注解和手动mock(RestTemplate.class)重复初始化,可能引发不必要的冲突。
修复方案
- 修正参数匹配规则:把
any(Map.class)替换为any(HttpEntity.class),确保和实际调用的参数类型一致; - 清理重复初始化:保留
@Mock注解的同时,在测试类上添加Mockito扩展注解(JUnit5用@ExtendWith(MockitoExtension.class),JUnit4用@RunWith(MockitoJUnitRunner.class)),让Mockito自动初始化Mock对象。
修改后的测试类代码:
@ExtendWith(MockitoExtension.class) class UtilsControllerTest { @Mock RestTemplate restTemplate; @Test void checkPermission() { boolean permitted = true; ResponseEntity<PermissionResponseModel> response = ResponseEntity.ok(new PermissionResponseModel(permitted)); // 匹配实际传递的HttpEntity类型参数 when(restTemplate.postForEntity(any(String.class), any(HttpEntity.class), eq(PermissionResponseModel.class))) .thenReturn(response); UtilsController utilsController = new UtilsController(); assertTrue(utilsController.checkPermission("69696969", Task.MAKE_REQUEST, restTemplate)); verify(restTemplate, times(1)).postForEntity(any(), any(), eq(PermissionResponseModel.class)); } }
额外提示
如果需要更精准的参数匹配,可以使用eq()指定具体参数值,或者用argThat()自定义匹配逻辑,确保Stub能准确命中实际调用场景。
内容的提问来源于stack exchange,提问作者Alexandru Grigore
相关产品推荐
相关产品推荐

