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

Mockito数据源单元测试在Debug模式下执行异常排查

解决TestNG+Mockito调试时ResultSet循环只执行一次的问题

嘿,我之前也碰到过一模一样的坑!这事儿跟Mockito本身没啥关系,锅得甩给IntelliJ的调试器——它偷偷帮你“做了点额外工作”,导致你的预设返回值被提前消耗了。

问题根源

你用Mockito.when(mockResultSet.next()).thenReturn(true, true, false)预设了三次调用的返回值:第一次true,第二次true,第三次false。但调试的时候,IntelliJ的变量视图为了显示ResultSet的内容,会自动调用它的next()方法来遍历结果集——这就相当于提前用掉了一个true!等你代码走到while (rs.next())的时候,剩下的返回值就变成了true, false,自然循环只执行一次就退出了。而正常运行时没有调试器的额外调用,所以预设的返回值序列能正常生效。

解决办法

这里有几个实用的方案,你可以按需选:

  • 关闭调试器的自动求值
    在IntelliJ的调试界面,找到「Variables」面板右上角的设置图标(齿轮),取消勾选「Enable auto expressions」或者「Auto evaluate expressions」选项。这样调试器就不会主动调用对象的方法来生成预览了,你的ResultSet的next()调用次数就完全由代码控制。

  • 调试时避免直接查看ResultSet变量
    如果你不想关自动求值,那调试的时候别点开mockResultSet的变量详情——一旦点开,调试器就会触发next()调用。可以改成在循环内部加日志或者打印语句,比如在ProjectDao的循环里加一行LOG.debug("当前循环执行,处理数据"),这样不用看ResultSet变量也能知道循环执行了几次。

  • 改用更鲁棒的Mock方式(可选)
    如果你担心这类调试干扰,也可以用Mockito的Answer来手动控制返回值,比如跟踪调用次数:

    AtomicInteger callCount = new AtomicInteger(0);
    Mockito.when(mockResultSet.next()).thenAnswer(invocation -> {
        int count = callCount.getAndIncrement();
        return count < 2; // 前两次返回true,第三次及以后返回false
    });
    

    这种方式不管调试器额外调用几次,只要代码里的调用次数是两次,就能正常触发两次循环(当然如果调试器调用太多,还是会影响,但一般调试时的额外调用不会太频繁)。

验证方法

改完之后,你可以再调试试试:如果关闭了自动求值,断点停在while (rs.next())时,不要碰ResultSet变量,直接按步过(F8),就能看到循环执行两次了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 04:16:45