MockMVC with a @Query in my Repository or refactor my controller to not use it?

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

MockMVC with a @Query in my Repository or refactor my controller to not use it?

问题

我在我的存储库中有一个@Query,根据SQL查询将数据返回给我的控制器,我该如何模拟这个过程?

这是我的存储库:

  1. package movieweb.movies.repository;
  2. import movieweb.movies.models.UserMovies;
  3. import org.springframework.data.jpa.repository.Query;
  4. import org.springframework.data.repository.CrudRepository;
  5. import org.springframework.stereotype.Repository;
  6. import java.util.List;
  7. @Repository
  8. public interface UserMoviesRepository extends CrudRepository<UserMovies, Integer> {
  9. @Query(value = "select * from movies, user_movies where movies.movie_id = user_movies.movie_id and uname = ?1", nativeQuery = true)
  10. List<UserMovies> findByUname(String uname);
  11. }

这是我的控制器:

  1. package movieweb.movies.controllers;
  2. import movieweb.movies.models.Movies;
  3. import movieweb.movies.models.UserMovies;
  4. import movieweb.movies.repository.UserMoviesRepository;
  5. import org.apache.catalina.User;
  6. import org.springframework.beans.factory.annotation.Autowired;
  7. import org.springframework.data.jpa.repository.Query;
  8. import org.springframework.http.HttpStatus;
  9. import org.springframework.http.ResponseEntity;
  10. import org.springframework.web.bind.annotation.*;
  11. import java.util.List;
  12. @RestController
  13. public class UserMoviesController {
  14. @Autowired
  15. private UserMoviesRepository umRepository;
  16. @CrossOrigin
  17. @PostMapping(path = "/newUserMovie")
  18. public ResponseEntity<UserMovies> addNewUserMovie(@RequestBody UserMovies data){
  19. umRepository.save(data);
  20. return new ResponseEntity<UserMovies>(data, HttpStatus.CREATED);
  21. }
  22. @CrossOrigin
  23. @GetMapping(path="/getUserMovies")
  24. public List<UserMovies> getUsersMovies(){
  25. return (List<UserMovies>) umRepository.findAll();
  26. }
  27. @CrossOrigin
  28. @GetMapping(path = "/getUserMovies/{uname}")
  29. public List<UserMovies> getUserMovies(@PathVariable String uname){
  30. return umRepository.findByUname(uname);
  31. }
  32. @CrossOrigin
  33. @DeleteMapping(path ="/deleteUserMovies/{id}")
  34. ResponseEntity deleteUserMovie(@PathVariable Integer id) {
  35. umRepository.deleteById(id);
  36. return new ResponseEntity(HttpStatus.ACCEPTED);
  37. }
  38. @CrossOrigin
  39. @PutMapping("/usermovie/update/{id}")
  40. public ResponseEntity<UserMovies> updateMovie(@RequestBody UserMovies updateMovie, @PathVariable Integer id) {
  41. return umRepository.findById(id)
  42. .map(userMovies -> {
  43. userMovies.setMovieId(updateMovie.getMovieId());
  44. userMovies.setUname(updateMovie.getUname());
  45. umRepository.save(userMovies);
  46. return new ResponseEntity<UserMovies>(userMovies, HttpStatus.OK);
  47. })
  48. .orElseGet(() -> {
  49. updateMovie.setMovieId(id);
  50. umRepository.save(updateMovie);
  51. return new ResponseEntity<UserMovies>(updateMovie, HttpStatus.OK);
  52. });
  53. }
  54. }

这是我在测试中尝试做的:

  1. @Test
  2. void getUserMoviesPerUser() throws Exception {
  3. ArrayList<UserMovies> userMovies = new ArrayList<>();
  4. userMovies.add(new UserMovies(1, "jamie", 1));
  5. userMovies.add(new UserMovies(2, "joe", 1));
  6. userMovies.add(new UserMovies(3, "jamie", 2));
  7. userMovies.add(new UserMovies(4, "joe", 2));
  8. when(userMoviesRepository.findByUname("jamie")).thenReturn(userMovies);
  9. mockMvc.perform(get("/getUserMovies/{uname}", "jamie"))
  10. .andDo(print())
  11. .andExpect(jsonPath("$", hasSize(2)))
  12. .andExpect(jsonPath("$[0].userMovieID", is(1)))
  13. .andExpect(jsonPath("$[0].uname", is("jamie")))
  14. .andExpect(jsonPath("$[0].movieId", is(1)))
  15. .andExpect(jsonPath("$[1].userMovieID", is(3)))
  16. .andExpect(jsonPath("$[1].uname", is("jamie")))
  17. .andExpect(jsonPath("$[1].movieId", is(1)));
  18. Mockito.verify(userMoviesRepository, times(1)).findAll();
  19. }

我面临的问题是,当我运行上面的测试时,我没有像我预期的那样得到只有2条记录,而是得到了4条。这在我无法依赖SQL来运行测试方面是有道理的。是否有更好的方法编写我的控制器,以根据movie_id获取数据?

英文:

I have a @Query in my Repository that I return data to my controller based on a SQL Query, how would I mock this?

Here is my Repository

  1. package movieweb.movies.repository;
  2. import movieweb.movies.models.UserMovies;
  3. import org.springframework.data.jpa.repository.Query;
  4. import org.springframework.data.repository.CrudRepository;
  5. import org.springframework.stereotype.Repository;
  6. import java.util.List;
  7. @Repository
  8. public interface UserMoviesRepository extends CrudRepository&lt;UserMovies, Integer&gt; {
  9. @Query(value = &quot;select * from movies, user_movies where movies.movie_id = user_movies.movie_id and uname = ?1&quot;, nativeQuery = true)
  10. List&lt;UserMovies&gt; findByUname(String uname);
  11. }

Here is my Controller

  1. package movieweb.movies.controllers;
  2. import movieweb.movies.models.Movies;
  3. import movieweb.movies.models.UserMovies;
  4. import movieweb.movies.repository.UserMoviesRepository;
  5. import org.apache.catalina.User;
  6. import org.springframework.beans.factory.annotation.Autowired;
  7. import org.springframework.data.jpa.repository.Query;
  8. import org.springframework.http.HttpStatus;
  9. import org.springframework.http.ResponseEntity;
  10. import org.springframework.web.bind.annotation.*;
  11. import java.util.List;
  12. @RestController
  13. public class UserMoviesController {
  14. @Autowired
  15. private UserMoviesRepository umRepository;
  16. @CrossOrigin
  17. @PostMapping(path = &quot;/newUserMovie&quot;)
  18. public ResponseEntity&lt;UserMovies&gt; addNewUserMovie(@RequestBody UserMovies data){
  19. umRepository.save(data);
  20. return new ResponseEntity&lt;UserMovies&gt;(data, HttpStatus.CREATED);
  21. }
  22. @CrossOrigin
  23. @GetMapping(path=&quot;/getUserMovies&quot;)
  24. public List&lt;UserMovies&gt; getUsersMovies(){
  25. return (List&lt;UserMovies&gt;) umRepository.findAll();
  26. }
  27. @CrossOrigin
  28. @GetMapping(path = &quot;/getUserMovies/{uname}&quot;)
  29. public List&lt;UserMovies&gt; getUserMovies(@PathVariable String uname){
  30. return umRepository.findByUname(uname);
  31. }
  32. @CrossOrigin
  33. @DeleteMapping(path =&quot;/deleteUserMovies/{id}&quot;)
  34. ResponseEntity deleteUserMovie(@PathVariable Integer id) {
  35. umRepository.deleteById(id);
  36. return new ResponseEntity(HttpStatus.ACCEPTED);
  37. }
  38. @CrossOrigin
  39. @PutMapping(&quot;/usermovie/update/{id}&quot;)
  40. public ResponseEntity&lt;UserMovies&gt; updateMovie(@RequestBody UserMovies updateMovie, @PathVariable Integer id) {
  41. return umRepository.findById(id)
  42. .map(userMovies -&gt; {
  43. userMovies.setMovieId(updateMovie.getMovieId());
  44. userMovies.setUname(updateMovie.getUname());
  45. umRepository.save(userMovies);
  46. return new ResponseEntity&lt;UserMovies&gt;(userMovies, HttpStatus.OK);
  47. })
  48. .orElseGet(() -&gt; {
  49. updateMovie.setMovieId(id);
  50. umRepository.save(updateMovie);
  51. return new ResponseEntity&lt;UserMovies&gt;(updateMovie, HttpStatus.OK);
  52. });
  53. }
  54. }

And here is what I am trying to do in my test

  1. @Test
  2. void getUserMoviesPerUser() throws Exception{
  3. ArrayList&lt;UserMovies&gt; userMovies = new ArrayList&lt;&gt;();
  4. userMovies.add(new UserMovies(1, &quot;jamie&quot;, 1));
  5. userMovies.add(new UserMovies(2, &quot;joe&quot;, 1));
  6. userMovies.add(new UserMovies(3, &quot;jamie&quot;, 2));
  7. userMovies.add(new UserMovies(4, &quot;joe&quot;, 2));
  8. when(userMoviesRepository.findByUname(&quot;jamie&quot;)).thenReturn(userMovies);
  9. mockMvc.perform(get(&quot;/getUserMovies/{uname}&quot;, &quot;jamie&quot;))
  10. .andDo(print())
  11. .andExpect(jsonPath(&quot;$&quot;, hasSize(2)))
  12. .andExpect(jsonPath(&quot;$[0].userMovieID&quot;, is(1)))
  13. .andExpect(jsonPath(&quot;$[0].uname&quot;, is(&quot;jamie&quot;)))
  14. .andExpect(jsonPath(&quot;$[0].movieId&quot;, is(1)))
  15. .andExpect(jsonPath(&quot;$[1].userMovieID&quot;, is(3)))
  16. .andExpect(jsonPath(&quot;$[1].uname&quot;, is(&quot;jamie&quot;)))
  17. .andExpect(jsonPath(&quot;$[1].movieId&quot;, is(1)));
  18. Mockito.verify(userMoviesRepository, times(1)).findAll();
  19. }

The problem I am facing is when I run the test above I am not getting back just 2 records like I would expect, I get back 4. This makes sense in the fact that I cant depend on SQL to run tests. Is there a better way to write my controller to get the data based on movie_id?

答案1

得分: 2

  1. @Test
  2. void getUserMoviesPerUser() throws Exception {
  3. ArrayList<UserMovies> userMovies = new ArrayList<>();
  4. userMovies.add(new UserMovies(1, "jamie", 1));
  5. userMovies.add(new UserMovies(2, "joe", 1));
  6. when(userMoviesRepository.findByUname("jamie")).thenReturn(userMovies);
  7. mockMvc.perform(get("/getUserMovies/{uname}", "jamie"))
  8. .andDo(print())
  9. .andExpect(jsonPath("$", hasSize(2)))
  10. .andExpect(jsonPath("$[0].userMovieID", is(1)))
  11. .andExpect(jsonPath("$[0].uname", is("jamie")))
  12. .andExpect(jsonPath("$[0].movieId", is(1)))
  13. .andExpect(jsonPath("$[1].userMovieID", is(3)))
  14. .andExpect(jsonPath("$[1].uname", is("jamie")))
  15. .andExpect(jsonPath("$[1].movieId", is(1)));
  16. Mockito.verify(userMoviesRepository, times(1)).findAll();
  17. }
英文:

In your code you are creating 4 records for mocking then simply remove 2 of them so that you have 2 records as response.

  1. @Test
  2. void getUserMoviesPerUser() throws Exception{
  3. ArrayList&lt;UserMovies&gt; userMovies = new ArrayList&lt;&gt;();
  4. userMovies.add(new UserMovies(1, &quot;jamie&quot;, 1));
  5. userMovies.add(new UserMovies(2, &quot;joe&quot;, 1));
  6. when(userMoviesRepository.findByUname(&quot;jamie&quot;)).thenReturn(userMovies);
  7. mockMvc.perform(get(&quot;/getUserMovies/{uname}&quot;, &quot;jamie&quot;))
  8. .andDo(print())
  9. .andExpect(jsonPath(&quot;$&quot;, hasSize(2)))
  10. .andExpect(jsonPath(&quot;$[0].userMovieID&quot;, is(1)))
  11. .andExpect(jsonPath(&quot;$[0].uname&quot;, is(&quot;jamie&quot;)))
  12. .andExpect(jsonPath(&quot;$[0].movieId&quot;, is(1)))
  13. .andExpect(jsonPath(&quot;$[1].userMovieID&quot;, is(3)))
  14. .andExpect(jsonPath(&quot;$[1].uname&quot;, is(&quot;jamie&quot;)))
  15. .andExpect(jsonPath(&quot;$[1].movieId&quot;, is(1)));
  16. Mockito.verify(userMoviesRepository, times(1)).findAll();
  17. }

答案2

得分: 0

  1. @Test
  2. void getUserMoviesPerUser() throws Exception{
  3. ArrayList<UserMovies> userMovies = new ArrayList<>();
  4. userMovies.add(new UserMovies(1, "jamie", 1));
  5. userMovies.add(new UserMovies(3, "jamie", 2));
  6. when(userMoviesRepository.findByUname("jamie")).thenReturn(userMovies);
  7. mockMvc.perform(get("/getUserMovies/{uname}", "jamie"))
  8. .andDo(print())
  9. .andExpect(jsonPath("$", hasSize(2)))
  10. .andExpect(jsonPath("$[0].userMovieID", is(1)))
  11. .andExpect(jsonPath("$[0].uname", is("jamie")))
  12. .andExpect(jsonPath("$[0].movieId", is(1)))
  13. .andExpect(jsonPath("$[1].userMovieID", is(3)))
  14. .andExpect(jsonPath("$[1].uname", is("jamie")))
  15. .andExpect(jsonPath("$[1].movieId", is(1)));
  16. Mockito.verify(userMoviesRepository, times(1)).findAll();
  17. }
英文:

I think you need to return the only records you were expecting. like

  1. @Test
  2. void getUserMoviesPerUser() throws Exception{
  3. ArrayList&lt;UserMovies&gt; userMovies = new ArrayList&lt;&gt;();
  4. userMovies.add(new UserMovies(1, &quot;jamie&quot;, 1));
  5. userMovies.add(new UserMovies(3, &quot;jamie&quot;, 2));
  6. when(userMoviesRepository.findByUname(&quot;jamie&quot;)).thenReturn(userMovies);
  7. mockMvc.perform(get(&quot;/getUserMovies/{uname}&quot;, &quot;jamie&quot;))
  8. .andDo(print())
  9. .andExpect(jsonPath(&quot;$&quot;, hasSize(2)))
  10. .andExpect(jsonPath(&quot;$[0].userMovieID&quot;, is(1)))
  11. .andExpect(jsonPath(&quot;$[0].uname&quot;, is(&quot;jamie&quot;)))
  12. .andExpect(jsonPath(&quot;$[0].movieId&quot;, is(1)))
  13. .andExpect(jsonPath(&quot;$[1].userMovieID&quot;, is(3)))
  14. .andExpect(jsonPath(&quot;$[1].uname&quot;, is(&quot;jamie&quot;)))
  15. .andExpect(jsonPath(&quot;$[1].movieId&quot;, is(1)));
  16. Mockito.verify(userMoviesRepository, times(1)).findAll();
  17. }

huangapple
  • 本文由 发表于 2020年3月16日 09:44:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/60699415.html
匿名

发表评论

匿名网友

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

确定