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

Mockito模拟List在单元测试中遍历异常的原因与解决

Mock List导致单元测试异常的原因与修复方案

问题根源

你只Mock了listMock.get(0)的返回值,但Mockito生成的Mock对象中,未显式指定行为的方法会返回对应类型的默认值:

  • isEmpty():boolean类型默认返回false,所以你的assertFalse(listMock.isEmpty())能通过,但这不是因为列表真的包含元素
  • size():int类型默认返回0,导致Sum.sum()方法中的for循环条件i < list.size()(即i < 0)不成立,循环完全没执行,sum保持初始值0,这就是测试返回0而非预期42的核心原因

修复方案

方案1:Mock所有被调用的方法

为Sum.sum()中用到的isEmpty()、size()、get()方法都指定预期行为:

@Test void sum_single() {
  final List<Integer> listMock = Mockito.mock(List.class);
  Mockito.when(listMock.isEmpty()).thenReturn(false);
  Mockito.when(listMock.size()).thenReturn(1);
  Mockito.when(listMock.get(0)).thenReturn(42);

  assertEquals(42, Sum.sum(listMock));
}

方案2:使用Spy包装真实List

如果不想手动Mock每个方法,可以用Mockito Spy包装一个真实的List实例,未自定义的方法会自动调用真实List的逻辑:

@Test void sum_single() {
  final List<Integer> realList = new ArrayList<>();
  realList.add(42);
  final List<Integer> listSpy = Mockito.spy(realList);

  assertEquals(42, Sum.sum(listSpy));
}

方案3:连缀简化Mock代码

可以将多个方法的Mock逻辑连缀起来,让代码更简洁:

@Test void sum_single() {
  final List<Integer> listMock = Mockito.mock(List.class);
  Mockito.when(listMock.isEmpty()).thenReturn(false)
         .when(listMock.size()).thenReturn(1)
         .when(listMock.get(0)).thenReturn(42);

  assertEquals(42, Sum.sum(listMock));
}

额外说明:测试中assertFalse(listMock.isEmpty())和assertEquals(42, listMock.get(0))能通过,只是因为前者命中了Mockito的默认返回值,后者是你显式指定的行为,但这两个验证并没有覆盖Sum.sum()实际依赖的size()方法,才导致测试结果不符合预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 13:22:05