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

Spring中BDDMockito测试JPA分页查询时空指针异常的排查与解决

分析Mock测试中NullPointerException的原因及测试用例编写规范

异常原因分析

你碰到的NullPointerException本质是Mockito参数匹配不匹配导致的:

  • 在测试代码里,你给dao.findByDriverId预设的调用预期是:
    given(this.dao.findByDriverId(1L, PageRequest.of(0, 2))).willReturn(journeyPage);
    
  • 但实际在JourneyService的getJourneyOfUser方法中,调用dao时传入的Pageable是PageRequest.of(0,10)(因为你测试调用service时传的length参数是10)。

Mockito默认的参数匹配规则是严格的对象相等校验,PageRequest的equals方法会比较page、size等属性,这里size一个是2、一个是10,显然不相等,所以mock的dao方法不会返回你预设的journeyPage,而是返回null。当service里调用journeyPage.getContent()时,自然就抛出了NPE。

测试用例编写规范

针对这类Mockito测试场景,分享几个关键的编写规范:

1. 用参数匹配器替代硬编码参数

当不需要严格匹配某个具体Pageable对象时,使用Mockito的参数匹配器来灵活匹配:

// 匹配任意Long类型的driverId,任意Pageable对象
given(this.dao.findByDriverId(anyLong(), any(Pageable.class))).willReturn(journeyPage);

// 或者更精准:只匹配driverId为1L的情况,Pageable任意
given(this.dao.findByDriverId(eq(1L), any(Pageable.class))).willReturn(journeyPage);

这样不管service传入的PageRequest参数是什么,只要符合匹配器规则,都会返回预设结果。

2. 保持测试参数与mock预期一致

如果确实需要严格匹配参数,确保测试调用service的参数和mock时的参数完全一致:

// 测试调用时传入和mock一致的length=2
ResponseDto responseDto = this.journeyService.getJourneyOfUser(1L, 0, 2);

3. 添加mock方法调用验证

在测试结尾添加验证步骤,确认mock的dao方法是否被正确调用,能快速排查参数不匹配问题:

// 验证dao.findByDriverId被调用1次,参数是1L和PageRequest.of(0,10)
verify(this.dao, times(1)).findByDriverId(1L, PageRequest.of(0,10));

如果参数不匹配,Mockito会抛出Wanted but not invoked类的异常,帮你快速定位问题点。

4. 确保Mock注解生效

测试类要正确使用Mockito的注解驱动:

  • JUnit4:在测试类上添加@RunWith(MockitoJUnitRunner.class)
  • JUnit5:在测试类上添加@ExtendWith(MockitoExtension.class)
    否则@Mock和@InjectMocks可能无法生效,导致dao实例为null(虽然这次不是这个问题,但这是基础规范)。

5. 统一管理测试参数

对于PageRequest这类可通过参数构建的对象,用变量统一管理,避免硬编码错误:

int testPage = 0;
int testSize = 10;
Pageable testPageable = PageRequest.of(testPage, testSize);

// mock时使用统一变量
given(this.dao.findByDriverId(1L, testPageable)).willReturn(journeyPage);

// 调用service时也用同样的变量
ResponseDto responseDto = this.journeyService.getJourneyOfUser(1L, testPage, testSize);

这样能从根源上避免参数不一致的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:49:41