使用Mockito模拟JsonNode时返回List为null的单元测试问题求助
单元测试返回null问题排查与修复
核心原因
你遇到的返回null问题根因是**TypeReference匿名类实例匹配失败**:
测试代码中when规则里创建的new TypeReference<List<Car>>(){}实例,和被测方法内部创建的同声明TypeReference是两个完全独立的对象,Mockito默认按对象相等规则匹配方法入参,因此readValue调用没有命中预设的mock规则,返回了默认值null。
修复方案
方案1:使用参数匹配器适配任意TypeReference(快速修复)
修改readValue的mock规则,第二个参数用any(TypeReference.class)匹配所有TypeReference实例即可:
// 注意混合字面量和匹配器时,字面量需要用eq()包裹 when(mockObjectMapper.readValue(eq("Mock"), any(TypeReference.class))).thenReturn(carList);
方案2:复用TypeReference常量(更规范的实现)
在被测类中定义全局的TypeReference常量,被测方法和测试代码共用同一个实例,从根源避免匹配问题:
- 被测类新增常量定义:
private static final TypeReference<List<Car>> CAR_LIST_TYPE_REF = new TypeReference<List<Car>>() {};
- 调整被测方法的
readValue调用:
return objectMapper.readValue(items, CAR_LIST_TYPE_REF);
- 测试mock规则复用同一个常量:
when(mockObjectMapper.readValue("Mock", TestedClass.CAR_LIST_TYPE_REF)).thenReturn(carList);
其他可选排查点
如果修复后仍有问题,可以检查以下配置:
- 确认
sqsMessage已完成mock,sqsMessage.getBody()的返回值与readTree的mock入参匹配,不会返回null - 若使用PowerMock静态mock
StringEscapeUtils,需要在测试类上添加@RunWith(PowerMockRunner.class)和@PrepareForTest(StringEscapeUtils.class)注解,否则静态mock规则不生效 - 确认
node为mock对象,node.get("Message")调用返回的子节点实例存在,textValue()可以正常返回预设的"node"值
内容的提问来源于stack exchange,提问作者Programmer
相关产品推荐
相关产品推荐

