JUnit RestControllerTest for @PutMapping throws InvocationTargetException

huangapple go评论125阅读模式
英文:

JUnit RestControllerTest for @PutMapping throws InvocationTargetException

问题

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

但是测试PUT方法失败了,显示以下错误:

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

在调试模式下运行测试并跟踪时出现InvocationTargetException:

JUnit RestControllerTest for @PutMapping throws InvocationTargetException

我的RestController方法如下:

@PutMapping(value = "/{id}")
public ResponseEntity updateSongById(@PathVariable("id") Integer id, @RequestBody @Validated 
SongDto songDto) {
    // TODO 添加授权
    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();
}

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

非常感谢!!

英文:

I'm building a microservice using Spring Boot. I wrote an API with GET-, POST-, PUT-, DELETE- Methods, run the application and tested it using Postman - everything's working fine...

But testing the PUT-Method fails with

java.lang.AssertionError: Status expected:<204> but was:<400>

Running the test in debug-mode and stepping throw throws an InvocationTargetException:

JUnit RestControllerTest for @PutMapping throws InvocationTargetException

My RestController-Methods looks like this:

@PutMapping(value = &quot;/{id}&quot;)
public ResponseEntity updateSongById(@PathVariable(&quot;id&quot;) 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));
}

The SongRepository is just a simple Interface which extends JpaRepository<Song, Integer>.

My failing test looks like this:

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

And getValidSongDto() just provides a Dto used in my tests:

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

I really don't understand at the moment, what I did wrong to make this test fail and also couldn't find anything in the internet which helped me solving this problem, so far. So, therefor I'd be very thankful, if anybody could tell me what's wrong here and how to solve this issue.

Thank you very much!!

答案1

得分: 2

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

You need to return the value for songService.getSongById as shown below

@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(&quot;/rest/v1/songs/1&quot;)
            .content(songDtoJson)
            .contentType(MediaType.APPLICATION_JSON))
            .andExpect(status().isNoContent());
}

huangapple
  • 本文由 发表于 2020年9月14日 20:14:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/63884143.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定