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

Mockito存根时抛出NullInsteadOfMockException异常的原因排查

Mockito NullInsteadOfMockException 问题排查与解决

可能的原因及修复方案

1. Mock对象初始化顺序错误

这是最常见的原因:你在初始化测试对象sut之后才调用MockitoAnnotations.openMocks(this),导致注入的template还是null。

  • 错误写法:
    @Mock
    private NamedParameterJdbcTemplate template;
    private PointIssuanceLookupDao sut;
    
    @Before
    public void setUp() {
        sut = new PointIssuanceLookupDao(template); // 此时template未被Mock初始化,为null
        MockitoAnnotations.openMocks(this);
    }
    
  • 正确写法:
    @Mock
    private NamedParameterJdbcTemplate template;
    private PointIssuanceLookupDao sut;
    
    @Before
    public void setUp() {
        MockitoAnnotations.openMocks(this); // 先初始化所有@Mock注解的对象
        sut = new PointIssuanceLookupDao(template); // 再用已初始化的Mock创建测试对象
    }
    

2. 注解包导入错误

确保你用的是Mockito的@Mock注解,而非其他框架(比如Spring)的同名注解。检查导入语句:

  • 正确导入:import org.mockito.Mock;

3. JUnit版本适配问题

如果使用JUnit 5,建议直接用MockitoExtension替代手动调用openMocks,避免初始化顺序问题:

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

@ExtendWith(MockitoExtension.class)
public class PointIssuanceLookupDaoTest {
    @Mock
    private NamedParameterJdbcTemplate template;
    private PointIssuanceLookupDao sut;

    @BeforeEach
    public void setUp() {
        sut = new PointIssuanceLookupDao(template);
    }
}

4. 存根代码引用对象错误

检查存根语句,确保直接使用template对象而非sut内部的引用。比如不要写when(sut.getJdbcTemplate().query(...))(如果sut没有暴露正确的getter,会返回null),直接用:

when(template.query(anyString(), anyMap(), anyRowMapper())).thenReturn(yourTestData);

核心总结

本质问题是Mock对象未完成初始化就被注入到测试对象中,导致存根时template为null。只要保证openMocks(或MockitoExtension初始化)在sut创建之前执行,就能解决绝大多数这类问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 02:33:13