@PutMapping için JUnit RestControllerTest InvocationTargetException oluşturur

Sep 14 2020

Spring Boot kullanarak bir mikro hizmet oluşturuyorum. GET-, POST-, PUT-, DELETE- Metotları ile bir API yazdım, uygulamayı çalıştırdım ve Postman kullanarak test ettim - her şey yolunda gidiyor ...

Ancak PUT Metodunun test edilmesi başarısız olur

java.lang.AssertionError: Beklenen durum: <204> ancak şuydu: <400>

Testi hata ayıklama modunda çalıştırmak ve adım atma bir InvocationTargetException oluşturur:

RestController-Yöntemlerim şuna benzer:

@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> 'ı genişleten basit bir Arayüzdür.

Başarısız testim şuna benziyor:

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

Ve getValidSongDto () sadece testlerimde kullanılan bir Dto sağlar:

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

Şu anda gerçekten anlamıyorum, bu testi başarısız kılmak için neyi yanlış yaptığımı ve şu ana kadar internette bu sorunu çözmeme yardımcı olacak hiçbir şey bulamadım. Bu nedenle, biri bana burada neyin yanlış olduğunu ve bu sorunun nasıl çözüleceğini söylerse çok minnettar olurum.

Çok teşekkür ederim!!

Yanıtlar

2 SSK Sep 14 2020 at 21:02

Değeri songService.getSongByIdaşağıda gösterildiği gibi döndürmeniz gerekir

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