如何Mock JPA Repository save方法并修改入参ID避免空指针异常
解决Spring Data JPA Repository Mock导致的空指针问题
问题原因
服务层代码里第一次调用activityRepository.save(activity)后,需要通过activity.getId()获取ID生成number,但当前Mock仅返回tempActivity,并未修改传入的activity实例的id字段,导致activity.getId()返回null,触发空指针异常。
正确的Mock方式
方案1:让Mock的save方法直接给传入的Activity赋值ID
用doAnswer替代thenReturn,在save方法被调用时,直接修改传入的Activity对象,设置模拟的自增ID:
doAnswer(invocation -> { Activity inputActivity = invocation.getArgument(0); inputActivity.setId(1); // 设置模拟的自增ID值 return inputActivity; // 也可返回预设的tempActivity,只要传入对象有ID即可 }).when(activityRepository).save(any(Activity.class));
方案2:同步返回对象的ID到传入实例
如果需要返回预先定义的tempActivity,可以在doAnswer中将tempActivity的ID同步到传入的Activity实例:
// 先给模拟的返回对象设置ID tempActivity.setId(1); doAnswer(invocation -> { Activity inputActivity = invocation.getArgument(0); inputActivity.setId(tempActivity.getId()); return tempActivity; }).when(activityRepository).save(any(Activity.class));
验证两次save调用
服务层中调用了两次save,验证时需指定调用次数,还可验证参数是否正确:
// 验证save方法被调用两次 verify(activityRepository, times(2)).save(any(Activity.class)); // 可选:验证第二次save时number是否正确生成 ArgumentCaptor<Activity> activityCaptor = ArgumentCaptor.forClass(Activity.class); verify(activityRepository, times(2)).save(activityCaptor.capture()); List<Activity> savedActivities = activityCaptor.getAllValues(); assertEquals("D1", savedActivities.get(1).getNumber());
内容的提问来源于stack exchange,提问作者GuitarFans
相关产品推荐
相关产品推荐

