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

Spring MongoDB单元测试空指针异常问题求助

Spring Boot MongoDB单元测试NullPointerException问题解决

错误原因

你在测试中用@Mock创建的GarageRepository是Mock对象,这类对象的所有方法默认返回null。当调用garageRepository.save(testGarage)时,未配置Mock的返回行为,所以返回null,导致savedGarage为null,后续调用savedGarage.getCarModel()触发了NullPointerException。

另外,你的测试逻辑偏离了单元测试目标:测试GarageService应该调用Service的业务方法,而非直接操作Repository。

修正后的测试代码

调整测试逻辑,聚焦测试GarageService.addToGarage方法,并正确配置Mock行为:

@DisplayName("Garage Service Test")
@DataMongoTest
class GarageServiceTest {

    @Mock
    private GarageRepository garageRepository;
    private GarageService garageService;

    @BeforeEach
    void setUp() {
        MockitoAnnotations.openMocks(this);
        garageService = new GarageService(garageRepository);
    }

    @Test
    @DisplayName("新增未存在的车型到车库")
    void testAddToGarage() {
        // 准备测试数据
        Garage testGarage = new Garage();
        testGarage.setId("630ca281f12905d5f5249f08");
        testGarage.setCarModel("Shelby Cobra");
        testGarage.setHP(485);
        testGarage.setYear(1965);
        testGarage.setDesigner("Carroll Shelby");

        // 配置Mock行为:查询车型返回空,模拟车型不存在
        Mockito.when(garageRepository.findByCarModel("Shelby Cobra")).thenReturn(Optional.empty());
        // 配置save方法返回传入对象,模拟保存成功
        Mockito.when(garageRepository.save(testGarage)).thenReturn(testGarage);

        // 调用Service业务方法
        garageService.addToGarage(testGarage);

        // 验证save方法被调用1次
        Mockito.verify(garageRepository, Mockito.times(1)).save(testGarage);
    }

    @Test
    @DisplayName("新增已存在的车型抛出异常")
    void testAddToGarageWithExistingModel() {
        // 准备测试数据
        Garage testGarage = new Garage();
        testGarage.setCarModel("Shelby Cobra");

        // 配置Mock行为:查询车型返回存在的对象,模拟车型已存在
        Mockito.when(garageRepository.findByCarModel("Shelby Cobra")).thenReturn(Optional.of(testGarage));

        // 验证调用方法时抛出指定异常
        IllegalStateException exception = Assertions.assertThrows(IllegalStateException.class, () -> {
            garageService.addToGarage(testGarage);
        });

        // 断言异常信息正确
        Assertions.assertEquals("This Car model is already in our garage!", exception.getMessage());
        // 验证save方法未被调用
        Mockito.verify(garageRepository, Mockito.never()).save(testGarage);
    }
}

关键要点说明

  • 用Mockito.when()配置Mock方法的返回值,避免调用Repository方法返回null。
  • 单元测试要聚焦Service层业务逻辑:验证调用Service方法后,Repository方法是否按预期调用,业务规则(如重复车型抛异常)是否生效。
  • 用Mockito.verify()确认Repository方法的调用次数,保障业务逻辑正确性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 12:01:05