You need to enable JavaScript to run this app. 使用Mockito编写Spring单元测试时,Stub仓储层触发NPE问题排查
优惠活动
大模型
产品
解决方案
定价
更多

使用Mockito编写Spring单元测试时,Stub仓储层触发NPE问题排查

单元测试空指针问题排查

问题描述

  • 编写仓储层Mock存根逻辑时抛出空指针异常,无法定位根因
  • 当前测试无复杂业务校验需求,仅需明确异常触发原因

代码定义

仓储层接口

@Repository
public interface ItemRepository extends CrudRepository<Item, String> {}

业务服务实现

@Service
public class ItemService {

    @Autowired
    ItemRepository itemRepository;

    @Autowired
    SteamMarketItemService steamMarketItemService;

    public void addItem(Item item) {
        itemRepository.save(item);
    }

    public List<Item> getAllItems() {
        return (List<Item>) itemRepository.findAll();
    }
}

单元测试实现

@RunWith(MockitoJUnitRunner.class)
class ItemServiceTest {

    @Mock
    ItemRepository itemRepository;

    @InjectMocks
    ItemService itemService;

    @Test
    void getAllItems_shouldReturnListOfItems() {
        //given
        List<Item> itemList = Collections.singletonList(new Item());
        //when
        when(itemRepository.findAll()).thenReturn(itemList);
        List<Item> returnedItems = itemService.getAllItems();

        //then
        Assert.assertEquals(itemList,returnedItems);
    }
}

抛出的异常堆栈

java.lang.NullPointerException
    at itemServiceTest.getAllItems_shouldReturnListOfItems(ItemServiceTest.java:34)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1507)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1507)
    at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
    at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)
    at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)

根因分析

该类空指针的核心触发逻辑是Mockito的对象初始化流程未被执行,导致测试类中被@Mock、@InjectMocks修饰的字段全为null,调用方法时触发空指针。

注意:@InjectMocks仅会自动注入测试类中已声明对应Mock类型的依赖,未声明Mock的注入字段会保持null值。由于当前测试方法未调用steamMarketItemService这类未声明Mock的字段,因此该类依赖缺失不会直接触发本次空指针异常。
常见触发场景:

  • 测试框架版本混用:测试类运行在JUnit5(Jupiter)引擎下,但使用了JUnit4专属的@RunWith(MockitoJUnitRunner.class)注解。该注解在JUnit5环境下完全不生效,不会触发Mockito的初始化逻辑,所有测试类内的依赖字段保持默认null值
  • 版本不兼容:mockito-core与junit的依赖版本存在冲突,导致Mockito runner无法正常加载执行

修复方案

  • 若使用JUnit4引擎:确认依赖版本兼容,保留现有注解体系即可
  • 若使用JUnit5引擎:移除@RunWith(MockitoJUnitRunner.class)注解,替换为Mockito对应的JUnit5扩展注解@ExtendWith(MockitoExtension.class),保证mock初始化逻辑正常执行
  • 补充缺失的静态依赖导入:确认导入org.mockito.Mockito.when、对应测试框架的断言类,避免编译期通过、运行期报错的问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.10 01:06:00