【问题标题】:spring why mocked method throws exception when optional existsspring 为什么在可选存在时模拟方法会抛出异常
【发布时间】:2022-01-21 14:20:06
【问题描述】:

我有这样的端点:

@PostMapping("/departure")
public ResponseEntity<String> departure(@RequestBody CarAtGateModel carAtGateModel) throws UnidentifiedCarException {
    CarAndParkingEntity carAndParkingEntity = carsAndParkingsRepository.findByIdCar(
            carAtGateModel.getCarEntity().getIdCar()).orElseThrow(() -> new UnidentifiedCarException());

    carAndParkingEntity.setIdParking("-1");
    carsAndParkingsRepository.flush();
    return new ResponseEntity<>(responsesMessages.gateUp(), HttpStatus.OK);
}

接下来我想用模拟做一些测试,比如:

@Test
public void departureWorksWhenCarOnDepartureIsRecognized() {
    //given
    carsAndParkingsRepository = mock(CarsAndParkingsRepository.class);
    CarAndParkingEntity carAndParkingEntity = new CarAndParkingEntity();
    
    CarAtGateModel carAtGateModel =  new CarAtGateModel();
    CarEntity carEntity = new CarEntity();
    carEntity.setIdCar("-1");
    carEntity.setProducer("a");
    carEntity.setModel("b");
    carEntity.setWidth(1.6);
    carEntity.setPowerType(PowerType.PB);
    carAtGateModel.setCarEntity(carEntity);
    carAtGateModel.setParkingId("parkingId");

    //when
    when(carsAndParkingsRepository.findByIdCar(carEntity.getIdCar())).thenReturn(Optional.of(carAndParkingEntity));
    HttpEntity<CarAtGateModel> request = new HttpEntity<>(carAtGateModel);
    ResponseEntity<String> response = testRestTemplate.postForEntity("/departure", request, String.class);

    //then
    assertEquals(200, response.getStatusCodeValue());
}

返回可选的模拟存储库正常工作,它返回carAndParkingEntity。 但是测试没有通过,因为它抛出了UnidentifiedCarException,我不明白为什么当carsAndParkingsRepository.findByIdCar(carEntity.getIdCar()) 返回可选时我会得到异常,所以它应该存在......

【问题讨论】:

  • 您在测试方法中模拟了存储库,但它是如何注入到您的控制器中的?这只是一个猜测,因为我们看不到整个测试类设置,但您可能需要使用 @Mock 或 @MockBean 注释将存储库声明为测试类的成员变量,并将 @InjectMocks 添加到控制器.
  • 我有公共 CarsAndParkingsRepository carsAndParkingsRepository;在设置中我添加了 carsAndParkingsRepository = mock(CarsAndParkingsRepository.class);

标签: spring testing exception mocking


【解决方案1】:

您提供的代码不足,无法正确识别问题。据我所知,您的模拟存储库没有注入控制器。因此,您不能期望控制器中的存储库以您在测试中声明的方式运行。

这里是一个如何在Spring中测试web层的例子https://spring.io/guides/gs/testing-web/

提示:您不应在 Web 层中使用存储库或业务逻辑。这只是可怕的做法。将所有逻辑分成单独的层并模拟它。然后,您可以仅针对您的逻辑进行单独的单元测试。测试您的 Web 层不应包括测试您的存储库访问或业务逻辑

【讨论】:

    猜你喜欢
    • 2013-08-10
    • 2016-06-15
    • 2021-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多