Home > database >  How to do integration tests with mocked service
How to do integration tests with mocked service

Time:01-31

I'm working at a small parking service REST API. For example I have endpoint:

@RequestMapping("/departure")
public ResponseEntity<String> departure(@RequestBody CarAtGateModel carAtGateModel) throws Exception {
    return parkingService.carDeparture(carAtGateModel.getCarEntity().getIdCar());
}

method parkingService.carDeparture looks like this:

public ResponseEntity<String> carDeparture(String carID) throws UnidentifiedCarException {
    CarAndParkingIDsEntity carAndParkingIDsEntity = carAndParkingIDsRepository.findByIdCar(carID);

    if (carAndParkingIDsEntity == null) {
        throw new UnidentifiedCarException();
    } else {
        carAndParkingIDsEntity.setIdParking("-1");
        carAndParkingIDsRepository.flush();
        return new ResponseEntity<>("Gate up", HttpStatus.OK);
    }
}

And the problem is when I'm trying to do some integration tests. Unit tests for parking service pass correctly but I don't know exactly what should I do for integration tests. I was thinking about something like. Mock carAtGateModel (it's carId and ParkingId) and send it to the endpoint and then mock parkingservice because I'm using it inside and I don't want to change data in the database.

when(parkingService.carDeparture(anyString())).thenReturn(new ResponseEntity<>("Gate up", 
HttpStatus.OK));    
HttpEntity<CarAtGateModel> request = new HttpEntity<>(carAtGateModel);
    ResponseEntity<String> response = testRestTemplate.postForEntity("/departure", request, 
String.class);

CodePudding user response:

Okey, so I added @Autowired MockMvc and @MockBean and I did something like this:

 @Test
public void test() throws Exception {
    ResponseEntity<String> response = new ResponseEntity<>("Gate up", HttpStatus.OK);
    CarAtGateModel carAtGateModel = mock(CarAtGateModel.class);
    CarEntity carEntity = mock(CarEntity.class);
    when(carAtGateModel.getCarEntity()).thenReturn(carEntity);
    when(carAtGateModel.getCarEntity().getIdCar()).thenReturn("ID");
    when(parkingService.carDeparture(carAtGateModel.getCarEntity().getIdCar())).thenReturn(response);
    //when(parkingService.carDeparture(anyString())).thenReturn(response);

    mockMvc.perform(MockMvcRequestBuilders.post("/departure"))
            .andDo(print())
            .andExpect(status().isOk());

}

and I am getting NullPointerException at

when(parkingService.carDeparture(carAtGateModel.getCarEntity().getIdCar())).thenReturn(response);

, but when I add

 parkingService = mock(ParkingService.class);

I am getting NullPointer on start of this line:

mockMvc.perform(MockMvcRequestBuilders.post("/departure"))
            .andDo(print())
            .andExpect(status().isOk());

CodePudding user response:

I would suggest you use @WebMvcTest instead to have a slice test (sort of integration test that focuses on a single application layer).

@ExtendWith(SpringExtension.class)
@WebMvcTest(YourController.class)
public class YourControllerIntegrationTest {

    @Autowired
    private MockMvc mockMvc;

    @MockBean
    private ParkingService parkingService;

    // Your test cases here
}

You would use mockMvc to perform an actual call to the REST endpoint with an actual CarAtGateModel object as JSON in the request body. You would also mock the behaviour of your ParkingService, thus focusing the test on your Controller.

  •  Tags:  
  • Related