JUnit RestControllerTest untuk @PutMapping akan menampilkan InvocationTargetException

Sep 14 2020

Saya sedang membangun layanan mikro menggunakan Spring Boot. Saya menulis API dengan Metode GET-, POST-, PUT-, DELETE-, menjalankan aplikasi dan mengujinya menggunakan Postman - semuanya berfungsi dengan baik ...

Tetapi pengujian Metode PUT gagal dengan

java.lang.AssertionError: Status yang diharapkan: <204> tetapi sebelumnya: <400>

Menjalankan pengujian dalam mode debug dan stepping throw akan menampilkan InvocationTargetException:

Metode RestController saya terlihat seperti ini:

@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 hanyalah Antarmuka sederhana yang memperluas JpaRepository <Song, Integer>.

Tes saya yang gagal terlihat seperti ini:

@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());
}

Dan getValidSongDto () hanya menyediakan Dto yang digunakan dalam pengujian saya:

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

Saya benar-benar tidak mengerti saat ini, kesalahan apa yang saya lakukan sehingga tes ini gagal dan juga tidak dapat menemukan apa pun di internet yang membantu saya menyelesaikan masalah ini, sejauh ini. Jadi, untuk itu saya akan sangat berterima kasih, jika ada yang bisa memberi tahu saya apa yang salah di sini dan bagaimana menyelesaikan masalah ini.

Terima kasih banyak!!

Jawaban

2 SSK Sep 14 2020 at 21:02

Anda perlu mengembalikan nilai songService.getSongByIdseperti yang ditunjukkan di bawah ini

@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());
}