9. 페이지 수정하기 데이터를 수정하기 위해서는 수정하고자 하는 데이터를 찾아야 하기 때문에 id값이 필요하다. input태그의 type속성을 hidden으로해 form을 작성한 후 나머지 데이터와 함께 id값을 넘겨주도록 한다.
post.html
<h2 > 게시글 작성</h2 > <div class ="card" style ="padding: 20px; border-radius: 15px; margin: 20px auto;" > <form class =" form-horizontal" method ="post" th:action ="@{/post}" th:object ="${postDto}" > <input type ="hidden" th:if ="*{id != null and id > 0}" th:field ="*{id}" /> <div class ="form-group" > <label > 제목</label > <div class ="col-sm-12" > <input type ="text" style ="border-radius: 5px;" class ="form-control" th:field ="*{title}" placeholder ="제목을 입력해 주세요." /> </div > </div > <div class ="form-group" > <label > 이름</label > <div class ="col-sm-12" > <input type ="text" style ="border-radius: 5px;" class ="form-control" th:field ="*{name}" placeholder ="이름을 입력해 주세요." /> </div > </div > <div class ="form-group" > <label > 내용</label > <div class ="col-sm-12" > <textarea class ="form-control" style ="height: 300px; border-radius: 5px;" th:field ="*{content}" placeholder ="내용을 입력해 주세요." > </textarea > </div > </div > <div class ="btn_wrap text-center" > <a th:href ="@{/}" class ="btn btn-default waves-effect waves-light" > 뒤로가기</a > <button type ="submit" class ="btn btn-primary waves-effect waves-light" > 저장하기</button > </div > </form > </div >
수정페이지로 이동하기 데이터를 수정위해서 URL경로를 통해 수정할 데이터의 id값을 받아온 후 해당 id값을 이용해 데이터를 조회한 뒤 기존 데이터를 반환하도록 한다. 내부 로직은 상세페이지를 가져오는 것과 똑같고 반환하는 템플릿만 다르게 반환한다.
PostController.java
@GetMapping("/post/{postId}/revise") public String getPostDetailsToRevise (@PathVariable("postId") Long id, Model model) { Post post = postService.getPostById(id); PostDto postDto = PostDto.builder() .id(post.getId()) .name(post.getName()) .title(post.getTitle()) .content(post.getContent()) .writeTime(post.getWriteTime()) .build(); model.addAttribute("postDto" , postDto); return "post" ; }
PostControllerTest.java
@Test @DisplayName("포스트 수정 페이지로 이동한다.") public void getPostDetailsToRevise () throws Exception { Post mockPost = Post.builder() .id(1L ) .name("tester" ) .title("test" ) .content("test" ) .writeTime(LocalDateTime.now()) .build(); given(postService.getPostById(1L )).willReturn(mockPost); ResultActions resultActions = mockMvc.perform(get("/post/1/revise" )); verify(postService).getPostById(1L ); resultActions .andExpect(status().isOk()); }
데이터 수정 요청 처리를 위한 Control 입력받은 데이터를 확인해 id값이 있을 경우에는 새로운 Post를 생성하게 id값이 없는 경우에는 기존 데이터를 Update하도록 한다.
form 태그는 Get과 Post 메소드만 사용할 수 있다. Patch 사용하려고 method까지 다 만들어 놨는데 나중가서 생각남…..
PostController.java
@PostMapping("/post") public String creatNewPost (@Valid @ModelAttribute("postDto") PostDto postDto) { if (postDto.getId() == null ) { postService.addPost(postDto); }else { postService.revisePostDetails(postDto); } return "redirect:/" ; }
수정요청에 대한 테스트 코드 작성 데이터 수정이 제대로 이루어진 경우 /
로 redirection이 이루어진다. 결과값으로 상태코드가 302로 뜨는지 확인하도록 한다.
PostControllerTest.java
@Test @DisplayName("포스트를 수정한다.") public void creatOrUpdatePost () throws Exception { PostDto postDto = PostDto.builder() .id(1L ) .name("tester" ) .title("test" ) .content("test" ) .build(); ResultActions resultActions = mockMvc.perform(post("/post" ) .flashAttr("postDto" , new PostDto ()) .param("id" , "1" ) .param("name" , "tester" ) .param("title" , "test" ) .param("content" , "test" ) ); verify(postService).updatePost(postDto); resultActions .andExpect(status().is3xxRedirection()) .andDo(print()) ; }
데이터 수정을 위한 Service 로직 여기서는 DB조회시 PostNotExistedException
예외가 일어날 일이 없다. Control에서 id값의 유무를 통해 create와 update로 나누어 실행하기 때문이다.
PostService.java
@Transactional public Post updatePost (PostDto postDto) { Post oldPost = postRepository.findById(postDto.getId()).orElseThrow(() -> new PostNotExistedException (postDto.getId())); oldPost.revise(postDto); return oldPost; }
데이터 수정에 대한 테스트 코드 작성 PostServiceTest.java
@Test @DisplayName("포스트 데이터를 업데이트 한다.") public void updatePost () { PostDto postDto = PostDto.builder() .id(1L ) .name("junit" ) .title("junitTest" ) .content("content" ) .build(); Post mockPost = Post.builder() .id(1L ) .name("tester" ) .title("test" ) .content("test" ) .writeTime(LocalDateTime.now()) .build(); given(postRepository.findById(1L )).willReturn(Optional.of(mockPost)); Post post = postService.updatePost(postDto); verify(postRepository).findById(1L ); assertThat(post.getName()).isEqualTo(postDto.getName()); assertThat(post.getTitle()).isEqualTo(postDto.getTitle()); assertThat(post.getContent()).isEqualTo(postDto.getContent()); }