@PutMapping 的 JUnit RestControllerTest 抛出 InvocationTargetException

JUnit RestControllerTest for @PutMapping throws InvocationTargetException

我正在使用 Spring Boot 构建微服务。我用 GET-、POST-、PUT-、DELETE- 方法 运行 编写了一个 API 应用程序并使用 Postman 对其进行了测试 - 一切正常...

但是测试 PUT 方法失败

java.lang.AssertionError:预期状态:<204> 但为:<400>

运行 调试模式下的测试和步进抛出抛出 InvocationTargetException:

我的 RestController-Methods 看起来像这样:

@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 的简单接口。

我失败的测试是这样的:

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

我现在真的不明白,我做错了什么导致这个测试失败,而且到目前为止在互联网上也找不到任何帮助我解决这个问题的东西。因此,如果有人能告诉我这里出了什么问题以及如何解决这个问题,我将非常感激。

非常感谢!!

您需要 return 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());
}