Jackson自定义反序列化器单元测试空指针异常问题求解
问题根因
- 第一类原因:
JsonUtils工具类内部问题- 类持有的
ObjectMapper静态实例未完成初始化,仅声明未赋值,调用convertValue时触发空指针 - API使用错误:
ObjectMapper.convertValue是用于Java对象之间的类型转换,不支持直接解析原始JSON字符串,传入字符串参数属于用法错误,应该使用readValue/readTree方法处理JSON字符串
- 类持有的
- 第二类原因:单元测试Mock逻辑缺失
你当前的Mockito写法没有模拟JsonParser.getCodec()的返回值,即使解决了JsonUtils的空指针,后续执行反序列化逻辑时调用jsonParser.getCodec()会返回null,依旧会触发空指针 - 额外问题:自定义反序列化器逻辑错误
代码中return codec.treeToValue(node,classAField.class);的写法错误,classAField是JsonNode实例,取它的Class会导致转换目标类型为JsonNode,并非你期望的MyClassA类型
修复方案
1. 修复JsonUtils工具类
确保ObjectMapper正确初始化,并且使用正确的API处理JSON字符串:
public class JsonUtils { // 全局初始化唯一的ObjectMapper实例 private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); public static <T> T jsonToObject(String json, Class<T> clazz) throws JsonProcessingException { // 用readValue解析JSON字符串,不要用convertValue return OBJECT_MAPPER.readValue(json, clazz); } }
2. 修复单元测试Mock逻辑
补充ObjectCodec的Mock配置,避免后续空指针:
@Test public void testDeserialize() throws IOException { String json = "{}"; // 也可以直接用ObjectMapper生成JsonNode,避免依赖你自己封装的JsonUtils JsonNode jsonNode = new ObjectMapper().readTree(json); // 模拟ObjectCodec ObjectCodec mockCodec = Mockito.mock(ObjectCodec.class); Mockito.when(parser.getCodec()).thenReturn(mockCodec); Mockito.when(mockCodec.readTree(parser)).thenReturn(jsonNode); // 如果你的测试用例覆盖classAField不为空的场景,还要补充treeToValue的Mock // Mockito.when(mockCodec.treeToValue(jsonNode, MyClassA.class)).thenReturn(你构造的期望返回值); MyClassA result = deserializer.deserialize(parser, context); Assert.assertEquals(result, MyClassA.builder().options(Collections.emptyList()).build()); }
3. 修复自定义反序列化器逻辑
修正类型转换的目标类型:
if (classAField != null) { // 目标类型指定为MyClassA,不要用classAField的Class return codec.treeToValue(node, MyClassA.class); }
内容的提问来源于stack exchange,提问作者Nikhil
相关产品推荐
相关产品推荐

