You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Mockito测试Criteria multiselect查询单元测试出现NullPointerException问题

问题原因排查

你遇到的空指针和where方法未调用的问题,核心是Mock对象的方法返回值缺失,执行到in查询构造行时链式调用过程中出现null值,代码提前抛出异常,自然无法执行到后续的where方法调用。具体缺失的Mock逻辑如下:

  • 所有Root实例的get(字段名)方法没有配置Mock返回值,默认返回null
  • CriteriaBuilder的in()方法返回的In实例没有Mock,且In.value()链式调用需要返回自身
  • 部分链式调用方法(如query.where、query.distinct、getResultList)没有配置返回值
修复方案

第一步:修正Mock对象的泛型匹配

将测试类中不匹配的泛型修正:

// 原写法错误,和业务代码的Object[]不匹配
// @Mock
// CriteriaQuery<Object> query;
// @Mock
// Query<Object> result;

// 修正后
@Mock
CriteriaQuery<Object[]> query;
@Mock
Query<Object[]> result;

第二步:补充缺失的Mock声明

新增需要用到的Mock实例:

@Mock
Path<String> bTypePath;
@Mock
Path<Object> bFieldIdPath, cFieldIdPath, aTypePath, aFieldIdPath, aNamePath, aAveragePath;
@Mock
In<String> inPredicate;
@Mock
Predicate equalPredicate;

第三步:测试方法中补充Mock逻辑

在dao.findAll()执行前补充如下返回配置:

// 配置所有Root.get()方法的返回值
Mockito.when(mockBRoot.get("fieldId")).thenReturn(bFieldIdPath);
Mockito.when(mockCRoot.get("fieldId")).thenReturn(cFieldIdPath);
Mockito.when(mockBRoot.get("type")).thenReturn(bTypePath);
Mockito.when(mockARoot.get("type")).thenReturn(aTypePath);
Mockito.when(mockARoot.get("fieldId")).thenReturn(aFieldIdPath);
Mockito.when(mockARoot.get("name")).thenReturn(aNamePath);
Mockito.when(mockARoot.get("average")).thenReturn(aAveragePath);

// 配置CriteriaBuilder的谓词构造方法返回
Mockito.when(criteriaBuilder.equal(Mockito.any(), Mockito.any())).thenReturn(equalPredicate);
Mockito.when(criteriaBuilder.in(bTypePath)).thenReturn(inPredicate);
// 配置In.value的链式调用返回自身
Mockito.when(inPredicate.value(Mockito.anyString())).thenReturn(inPredicate);

// 配置CriteriaQuery链式调用的返回
Mockito.when(query.multiselect(Mockito.any(Selection[].class))).thenReturn(query);
Mockito.when(query.where(Mockito.any(Predicate[].class))).thenReturn(query);
Mockito.when(query.distinct(Mockito.anyBoolean())).thenReturn(query);

// 配置最终查询结果返回
Mockito.when(result.getResultList()).thenReturn(Collections.emptyList());
补充说明

如果需要验证查询逻辑的正确性,建议额外编写集成测试,使用H2等内存数据库执行真实查询,单元测试仅用于验证DAO层的方法调用流程即可。

内容的提问来源于stack exchange,提问作者Rocco

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 17:09:01