Mock RestTemplate返回ResponseEntity时遇编译错误,如何解决?
单元测试编译错误排查与修复
问题场景
待测试的Emp类代码
public class Emp { public String getName() { ResponseEntity<LinkedHashMap> res = restTemplate.postForEntity(url, null, LinkedHashMap.class); return res.getBody().get("name"); } }
编写的单元测试代码
LinkedHashMap<String, String> map = new LinkedHashMap<>(); map.put("name", "foo"); ResponseEntity<LinkedHashMap> entity = new ResponseEntity<>(map, HttpStatus.OK); Mockito.when(restTemplate.postForEntity(Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(entity);
编译错误信息
java: no suitable method found for thenReturn(org.springframework.http.ResponseEntity<java.util.LinkedHashMap>)
问题原因
Mockito的any()是无类型限制的通配符匹配器,用它作为postForEntity的参数时,编译器无法推断方法的泛型类型,导致when方法推断出的返回类型和你传入的ResponseEntity<LinkedHashMap>类型不兼容,最终触发编译错误。
修复方案
有两种直接可行的修复方式:
方式一:使用带具体类型的匹配器
把无类型的any()替换为对应参数类型的匹配器,让编译器能准确推断泛型:
LinkedHashMap<String, String> map = new LinkedHashMap<>(); map.put("name", "foo"); ResponseEntity<LinkedHashMap> entity = new ResponseEntity<>(map, HttpStatus.OK); Mockito.when(restTemplate.postForEntity( Mockito.anyString(), // 匹配URL字符串类型 Mockito.any(Object.class), // 匹配请求体(原方法传null) Mockito.eq(LinkedHashMap.class) // 精确匹配第三个参数的Class类型 )).thenReturn(entity);
方式二:显式指定泛型类型
如果坚持使用any(),可以给when方法显式指定泛型类型,明确返回值的类型:
LinkedHashMap<String, String> map = new LinkedHashMap<>(); map.put("name", "foo"); ResponseEntity<LinkedHashMap> entity = new ResponseEntity<>(map, HttpStatus.OK); // 显式指定泛型类型,让编译器匹配thenReturn的参数 Mockito.<ResponseEntity<LinkedHashMap>>when( restTemplate.postForEntity(Mockito.any(), Mockito.any(), Mockito.any()) ).thenReturn(entity);
额外优化建议
原Emp类的getName方法中,res.getBody().get("name")返回的是Object类型,会触发编译警告,建议修改为强转+空值判断的安全写法:
public String getName() { ResponseEntity<LinkedHashMap> res = restTemplate.postForEntity(url, null, LinkedHashMap.class); LinkedHashMap body = res.getBody(); return body != null ? (String) body.get("name") : null; }
内容的提问来源于stack exchange,提问作者sachin p
相关产品推荐
相关产品推荐

