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
相关产品推荐
相关产品推荐

