【问题标题】:hibernate - why mocked method throws NullPointerExceptionhibernate - 为什么模拟方法抛出 NullPointerException
【发布时间】:2022-01-10 20:36:37
【问题描述】:

我正在尝试准备一些简单的停车服务 API,但我一直在测试。

我有 ParkingService 之类的:

@Service
@RequiredArgsConstructor
public class ParkingService {
      private final CarsAndParkingsRepository carsAndParkingsRepository;
      private final ParkingsRepository parkingsRepository;

以及存储库中的简单自定义方法

public boolean checkFreeSlots(String idParking) {
    return carsAndParkingsRepository.findAmountOfTakenSlotsOnParking(idParking)
            < parkingsRepository.findByIdParking(idParking).getNumberOfParkingSlots();
}

和测试:

 @Test
public void checkFreeSlotsIfIsCorrect() {
    //given

    //when
    when(carsAndParkingsRepository.findAmountOfTakenSlotsOnParking("5")).thenReturn(5);
    when(parkingsRepository.findByIdParking("5").getNumberOfParkingSlots()).thenReturn(10);
    when(parkingService.checkFreeSlots("5")).thenCallRealMethod();
    boolean result = parkingService.checkFreeSlots("5");

    //then
    assertEquals(true, result);
}

但问题是我在行得到 NullPointerException:

when(parkingsRepository.findByIdParking("5").getNumberOfParkingSlots()).thenReturn(10);

以前的模拟方法 when(carsAndParkingsRepository.findAmountOfTakenSlotsOnParking("5")).thenReturn(5) 工作正常,它的返回 5 但在下一行其他存储库抛出异常。 有没有其他方法可以测试它或者我做错了什么? Ofc,我已经模拟了存储库:)

【问题讨论】:

  • 存根时,方法会照常调用。 when(parkingsRepository.findByIdParking("5").getNumberOfParkingSlots()) 因为你没有存根 findByIdParking,所以它返回 null,因此是 NPE。
  • 我如何存根 findByIdParking?没听说过

标签: spring hibernate mocking mockito integration-testing


【解决方案1】:

问题出在:

when(parkingsRepository.findByIdParking("5").getNumberOfParkingSlots()).thenReturn(10);

when 的参数需要在调用之前进行评估:

  • parkingsRepository.findByIdParking("5") 被调用并返回 null
  • null.getNumberOfParkingSlots() 被调用并抛出 NPE

您有以下选择:

使用 POJO 进行停车

var parking5 = new Parking(
    5, //id
   10, //number of slots
   // ... other arguments
);
when(parkingsRepository.findByIdParking("5")).thenReturn(parking5);

这是首选选项,但如果您的对象难以构造(hibernate 实体不应该是这种情况),您可以使用模拟

使用停车场的模拟

var parking5 = mock(Parking.class);
when(parkingsRepository.findByIdParking("5")).thenReturn(parking5);
when(parking5.getNumberOfParkingSlots()).thenReturn(10);

请注意,您可以在此方法中使用链式调用,但这需要您按顺序存根方法。

var parking5 = mock(Parking.class);
when(parkingsRepository.findByIdParking("5")).thenReturn(parking5);
when(parkingsRepository.findByIdParking("5").getNumberOfParkingSlots()).thenReturn(10);

在我看来,第一种风格更易于使用,并且可以让您重新排序存根。

【讨论】:

  • 谢谢你,我花了半个晚上,用模拟做了几乎相同的解决方案,它工作正常。感谢您一步一步的解释:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-01-24
  • 1970-01-01
  • 2014-12-18
  • 2013-09-09
  • 2014-07-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多