首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >MockMvc测试发布请求

MockMvc测试发布请求
EN

Stack Overflow用户
提问于 2017-05-28 10:14:46
回答 3查看 14.1K关注 0票数 2

我的REST控制器中有以下post路由:

代码语言:javascript
运行
复制
     @RequestMapping(value = "", method = RequestMethod.POST, produces = 
    "application/json")
    public ResponseEntity saveMovie(@RequestBody Movie movie){
        movieService.saveMovie(movie);
        return new ResponseEntity<Movie>(movie, HttpStatus.OK);
    }

该路由使用一个服务将传入请求body的电影添加到数据存储中。服务方法的签名如下:

代码语言:javascript
运行
复制
    Movie saveMovie(Movie movie);

我已经为它编写了以下测试和一个辅助方法:

代码语言:javascript
运行
复制
      @Test
      public void saveMovie() throws Exception {
        Movie movie1 = new Movie();
        movie1.setImdbID("imdb1");
        movie1.setTitle("Meter");
        movie1.setYear("2015");
        movie1.setPoster("meter.jpg");

        when(movieService.saveMovie(movie1)).thenReturn(movie1);
        mockMvc.perform(post("/v1/api/movie")
                .contentType(MediaType.APPLICATION_JSON_UTF8)
                .content(asJsonString(movie1))
                .accept(MediaType.APPLICATION_JSON))
                .andExpect(status().isOk())                   
                .andExpect(content().contentType
                     (MediaType.APPLICATION_JSON_UTF8_VALUE));
                 verify(movieService, times(1)).saveMovie(movie1);
                 verifyNoMoreInteractions(movieService);
    }



    public static String asJsonString(final Object obj) {
        try {
            final ObjectMapper mapper = new ObjectMapper();
            final String jsonContent = mapper.writeValueAsString(obj);
            System.out.println(jsonContent);
            return jsonContent;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

我得到以下错误:

代码语言:javascript
运行
复制
    Argument(s) are different! Wanted:
     com.stackroute.ng2boot.service.MovieService#0 bean.saveMovie(
       com.stackroute.ng2boot.domain.Movie@ae372b9
     );
     -> at 

     com.stackroute.ng2boot.controllers.MovieRestControllerTest.
     saveMovie(MovieRestControllerTest.java:129)
     Actual invocation has different arguments:
    com.stackroute.ng2boot.service.MovieService#0 bean.saveMovie(
    com.stackroute.ng2boot.domain.Movie@2098d37d
    );
    -> at     
    com.stackroute.ng2boot.controllers.MovieRestController.
    saveMovie(MovieRestController.java:60)

除了保存和更新之外,我需要传递一个Movie JSON作为请求主体,其他路由都通过了测试。请分享您的宝贵意见。

提前谢谢。

EN

回答 3

Stack Overflow用户

发布于 2021-09-10 17:49:51

假设这是MovieService类:

代码语言:javascript
运行
复制
@Component
public class MovieService {

    private static List<Movie> movieList = new ArrayList<>();

    static {
        Movie m1 = new Movie("id1", "title1","2000", "poster1.jpg");
        Movie m2 = new Movie("id2", "title2","2001", "poster2.jpg");
        Movie m3 = new Movie("id3", "title3","2002", "poster3.jpg");
        Movie m4 = new Movie("id4", "title4","2003", "poster4.jpg");
        Movie m5 = new Movie("id5", "title5","2004", "poster5.jpg");

        movieList.add(m1);
        movieList.add(m2);
        movieList.add(m3);
        movieList.add(m4);
        movieList.add(m5);
    }

    public Movie saveMovie(Movie movie){
        movieList.add(movie);
        return movie;
    }
}

假设这是MovieController类:

代码语言:javascript
运行
复制
@RestController
public class MovieController {

    private final MovieService movieService;

    public MovieController(MovieService movieService) {
        this.movieService = movieService;
    }

    @PostMapping(value = "", produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity saveMovie(@RequestBody Movie movie){
        movieService.saveMovie(movie);
        return new ResponseEntity<>(movie, HttpStatus.OK);
    }
}

您可以使用MockMvc编写如下测试。该测试检查响应中的HttpStatus是否为预期的HttpStatus.OK,并检查saveMovie.saveMovie是否为movie6调用过一次。

代码语言:javascript
运行
复制
@RunWith(SpringRunner.class)
@WebMvcTest(MovieController.class)
public class MovieControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @MockBean
    private MovieService movieService;

    @Test
    public void saveMovie() throws Exception {
        Movie movie6 = new Movie("id6", "title6", "2006", "poster6.jpg");
        String movie6AsJson = new ObjectMapper().writeValueAsString(movie6);
        String url = "/";

        when(movieService.saveMovie(any(Movie.class))).thenReturn(movie6);

        RequestBuilder requestBuilder = MockMvcRequestBuilders.post(url)
            .accept(MediaType.APPLICATION_JSON)
            .contentType(MediaType.APPLICATION_JSON)
            .content(movie6AsJson);

        MvcResult mvcResult = mockMvc.perform(requestBuilder).andReturn();

        int actualResult = mvcResult.getResponse().getStatus();
        int expectedResult = HttpStatus.OK.value();

        assertEquals("Result not as expected!",expectedResult,actualResult);
        verify(movieService, times(1)).saveMovie(refEq(movie6));
    }

}
票数 1
EN

Stack Overflow用户

发布于 2017-09-27 22:04:47

你能不能试试:

代码语言:javascript
运行
复制
import static org.mockito.Matchers.refEq;
----
verify(movieService, times(1)).saveMovie(refEq(movie1));
票数 0
EN

Stack Overflow用户

发布于 2019-05-17 13:16:20

您应该尝试使用:

代码语言:javascript
运行
复制
verify(movieService).saveMovie(ArgumentMatchers.eq(movie1));

确保在Movie类中实现了equalshashCode方法也很好。

我注意到的另一件小事(然而,与您的问题无关)是您不需要同时使用times(1)verifyNoMoreInteractions(movieService)。默认情况下,Mockito.verify应该被调用一次。看看它的源代码:

代码语言:javascript
运行
复制
public static <T> T verify(T mock) {
    return MOCKITO_CORE.verify(mock, times(1));
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44223213

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档