JUnit RestControllerTest สำหรับ @PutMapping พ่น InvocationTargetException

Sep 14 2020

ฉันกำลังสร้างไมโครเซอร์วิสโดยใช้ Spring Boot ฉันเขียน API ด้วย GET-, POST-, PUT-, DELETE- วิธีการเรียกใช้แอปพลิเคชันและทดสอบโดยใช้บุรุษไปรษณีย์ - ทุกอย่างทำงานได้ดี ...

แต่การทดสอบ PUT-Method ล้มเหลวด้วย

java.lang.AssertionError: สถานะที่คาดหวัง: <204> แต่เป็น: <400>

การรันการทดสอบในโหมดดีบักและการขว้างแบบก้าวจะโยน InvocationTargetException:

วิธี RestController ของฉันมีลักษณะดังนี้:

@PutMapping(value = "/{id}")
public ResponseEntity updateSongById(@PathVariable("id") Integer id, @RequestBody @Validated 
SongDto songDto) {
    // TODO Add authorization
    SongDto song = songService.getSongById(id);
    if (song == null)
        return new ResponseEntity(HttpStatus.BAD_REQUEST);
    return new ResponseEntity(songService.updateSong(id, songDto), HttpStatus.NO_CONTENT);
}

songService.getSongById (id):

@Override
public SongDto getSongById(Integer id) {
    return songMapper.songToSongDto(songRepository.findById(id)
        .orElseThrow(NotFoundException::new));
}

SongRepository เป็นเพียงอินเทอร์เฟซธรรมดาที่ขยาย JpaRepository <Song, Integer>

การทดสอบล้มเหลวของฉันมีลักษณะดังนี้:

@Test
void updateSongById_success() throws Exception {
    when(songService.updateSong(anyInt(), any(SongDto.class))).thenReturn(getValidSongDto());
    String songDtoJson = objectMapper.writeValueAsString(getValidSongDto());
    mockMvc.perform(put("/rest/v1/songs/1")
            .content(songDtoJson)
            .contentType(MediaType.APPLICATION_JSON))
            .andExpect(status().isNoContent());
}

และ getValidSongDto () ให้ Dto ที่ใช้ในการทดสอบของฉัน:

private SongDto getValidSongDto() {
    return SongDto.builder()
            .id(1)
            .title("TestSongValid")
            .label("TestLabelValid")
            .genre("TestGenreValid")
            .artist("TestArtistValid")
            .released(1000)
            .build();
}

ตอนนี้ฉันไม่เข้าใจจริงๆว่าฉันทำอะไรผิดที่ทำให้การทดสอบนี้ล้มเหลวและไม่พบสิ่งใดในอินเทอร์เน็ตที่ช่วยฉันแก้ปัญหานี้ได้จนถึงตอนนี้ ดังนั้นฉันจะขอบคุณมากถ้าใครสามารถบอกฉันได้ว่ามีอะไรผิดปกติที่นี่และวิธีแก้ปัญหานี้

ขอบคุณมาก!!

คำตอบ

2 SSK Sep 14 2020 at 21:02

คุณต้องคืนค่าsongService.getSongByIdตามที่แสดงด้านล่าง

@Test
void updateSongById_success() throws Exception {
    
    when(songService.getSongById(Mockito.any())).thenReturn(getValidSongDto());
    
    when(songService.updateSong(anyInt(), any(SongDto.class))).thenReturn(getValidSongDto());
    
    String songDtoJson = objectMapper.writeValueAsString(getValidSongDto());
    
    mockMvc.perform(put("/rest/v1/songs/1")
            .content(songDtoJson)
            .contentType(MediaType.APPLICATION_JSON))
            .andExpect(status().isNoContent());
}