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

仅在IntelliJ Debugger中触发Mockito Unfinished Stubbing Exception的原因排查

为什么仅在IntelliJ调试Mockito Mock对象时会抛出UnfinishedStubbingException?

这个问题我之前排查过好几次,不是Mockito的Bug,而是调试器和Mockito内部校验机制交互时的典型认知盲区,咱们一步步拆解原因和解决办法:

核心原因分析

  1. 调试器的自动toString()调用
    IntelliJ调试面板在显示变量时,默认会自动调用对象的toString()方法来生成友好的显示文本。而Mockito的Mock对象内部有一套严格的Stubbing状态校验——当你还在编写Stubbing代码(比如when(repo.findById(1L)).thenReturn(...))的过程中,如果调试器此时触发了Mock对象的toString(),Mockito会认为你正在进行的Stubbing操作未完成,直接抛出UnfinishedStubbingException。

  2. 直接运行测试时无异常的原因
    直接运行测试时,程序不会触发调试器的变量监视逻辑,也就不会主动调用Mock对象的toString()。只要你的Stubbing代码最终是完整执行的,Mockito就不会抛出异常,测试自然能正常通过。

解决办法

针对这个场景,有几个实用的解决方式:

  • 调整断点位置:不要在Stubbing代码的中间(比如when(...)和thenReturn(...)之间)设置断点,把断点放在Stubbing代码全部执行完成之后的位置,避免调试器在Stubbing未完成时访问Mock对象。
  • 自定义Mock的toString():提前给Mock对象Stub好toString()方法,绕过Mockito的默认校验逻辑,比如:
    @Mock
    private CustomerChoiceRepository customerChoiceRepository;
    
    @BeforeEach
    void setUp() {
        // 先Stub toString(),避免调试时触发异常
        when(customerChoiceRepository.toString()).thenReturn("Mocked CustomerChoiceRepository");
        // 再Stub其他业务方法
        when(customerChoiceRepository.findById(anyLong())).thenReturn(Optional.empty());
    }
    
  • 修改IntelliJ调试设置:打开Settings -> Build, Execution, Deployment -> Debugger -> Data Views -> Java,取消勾选「Enable toString() object view」,或者在下方的「Exclude classes」中添加com.item.repository.jpa.CustomerChoiceRepository,让调试器不再自动调用该类Mock对象的toString()。

总结

这本质上是调试器的自动变量展示行为和Mockito的Stubbing状态校验规则冲突导致的,只要理解了两者的交互逻辑,调整代码或设置就能轻松解决。

内容的提问来源于stack exchange,提问作者ng.newbie

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 21:04:09