3. 새로운 Post 생성 요청 처리하기
데이터를 저장하는 로직은 DB에 접근을 하기 때문에 다음과 같은 로직을 추가해 DB에 데이터들이 제대로 저장되는지 확인한다. 어플리케이션을 실핸한 후 http://localhost:8080/h2-console 를 통해 데이터 베이스에 접근할 수 있다.
application.yml
spring: h2: console: enabled: true path: /h2-console datasource: username: sa password: url: jdbc:h2:mem:testdb driver-class-name: org.h2.Driver
|
/post
경로로 post 요청이 들어올 경우 입력된 정보들이 제대로 들어왔는지 Validation을 진행하고 문제가 없을 경우 데이터를 저장한다.
PostController.java
@PostMapping("/post") public String creatNewPost(@Valid @ModelAttribute("postDto") PostDto postDto) { postService.addPost(postDto); return "redirect:/"; }
|
생성 요청 테스트 코드 작성하기
MockBean 추가하기
PostController의 creatNewPost메소드 내에서는 PostService객체를 사용하기 때문에 테스트코드를 작성하기 위해서 해당 Mock 을 추가해줄 필요가 있다.
PostControllerTest.java
@MockBean private PostService postService;
|
PostService객체의 MockBean을 생성해주지 않으면 아래와 같은 오류로 테스트가 진행되지 않는다.
creatNewPost메소드 /post
경로로 post 요청에 대한 테스트 코드를 작성할 것이다.
- given메소드를 이용해 PostService가 반환할 객체에 대해 정의를 한다.
/post
경로로 post요청을 보내도록한다.
- 데이터를 보내기 위해서는 flashAttr 메소드를 이용해 플래시 스코프에 객체를 설정하도록한다.
- 요청이 완료된 후 리다이렉션(Status Code : 302) 이 제대로 이루어지는지 확인한다.
PostControllerTest.java
@Test @DisplayName("새로운 게시글 생성을 성공한다.") public void successCreateNewPost() throws Exception { Post mockPost = Post.builder() .id(1L) .title("test") .name("tester") .content("test") .writeTime(LocalDateTime.now()) .build();
given(postService.addPost(any())).willReturn(mockPost);
ResultActions resultActions = mockMvc.perform(post("/post") .flashAttr("postDto", new PostDto())
.param("title", "test") .param("name", "tester") .param("content", "test") );
resultActions .andExpect(status().is3xxRedirection()) .andDo(print());
verify(postService).addPost(any()); }
|
실패에 대한 테스트 코드 진행
Controller단에서의 Data Validation이 제대로 작동하는지 확인하기 위한 테스트 코드들이다. title, name, content 에 대한 값의 검증을 해줘야 하기 때문에 세가지 경우로 확인했다.
PostControllerTest.java
@Test @DisplayName("새로운 게시글 생성을 실패한다.") public void failCreateNewFailWithNoTitle() throws Exception { Post mockPost = Post.builder() .id(1L) .title("test") .name("tester") .content("test") .writeTime(LocalDateTime.now()) .build();
given(postService.addPost(any())).willReturn(mockPost);
ResultActions resultActions = mockMvc.perform(post("/post") .flashAttr("postDto", new PostDto()) .param("name", "tester") .param("content", "test") );
resultActions .andExpect(status().isBadRequest()) .andDo(print()); }
@Test @DisplayName("새로운 게시글 생성을 실패한다.") public void failCreateNewFailWithNoName() throws Exception { Post mockPost = Post.builder() .id(1L) .title("test") .name("tester") .content("test") .writeTime(LocalDateTime.now()) .build();
given(postService.addPost(any())).willReturn(mockPost);
ResultActions resultActions = mockMvc.perform(post("/post") .flashAttr("postDto", new PostDto()) .param("title", "test") .param("content", "test") );
resultActions .andExpect(status().isBadRequest()) .andDo(print()); }
@Test @DisplayName("새로운 게시글 생성을 실패한다.") public void failCreateNewFailWithNoContent() throws Exception { Post mockPost = Post.builder() .id(1L) .title("test") .name("tester") .content("test") .writeTime(LocalDateTime.now()) .build();
given(postService.addPost(any())).willReturn(mockPost);
ResultActions resultActions = mockMvc.perform(post("/post") .flashAttr("postDto", new PostDto()) .param("title", "test") .param("name", "tester") );
resultActions .andExpect(status().isBadRequest()) .andDo(print()); }
|
데이터 저장하기
PostRepository 객체를 통해 데이터 저장을 진행한다.
PostService.java
@Service @RequiredArgsConstructor public class PostService { private final PostRepository postRepository;
@Transactional public Post addPost(PostDto postDto) { Post post = Post.builder() .title(postDto.getTitle()) .name(postDto.getName()) .content(postDto.getContent()) .writeTime(LocalDateTime.now()) .build();
return postRepository.save(post); } }
|
저장로직에 대한 테스트 코드 작성
PostService 객체의 addPost가 실행된 후 값이 제대로 반환됐는지 확인한 후 PostRepository 객체에서 save 메소드가 호출됐는지 확인한다.
PostServiceTest.java
class PostServiceTest {
@Mock private PostRepository postRepository;
private PostService postService;
@BeforeEach public void init() { MockitoAnnotations.openMocks(this);
postService = new PostService(postRepository); }
@Test @DisplayName("새로운 포스트를 추가한다.") @Transactional public void addPost() { PostDto postDto = PostDto.builder() .title("test") .name("tester") .content("test") .writeTime(LocalDateTime.now()) .build();
Post mockPost = Post.builder() .id(1L) .title("test") .name("tester") .content("test") .writeTime(LocalDateTime.now()) .build();
given(postRepository.save(any())).willReturn(mockPost);
Post returnPost = postService.addPost(postDto);
assertThat(returnPost.getId()).isEqualTo(mockPost.getId()); assertThat(returnPost.getTitle()).isEqualTo(mockPost.getTitle()); assertThat(returnPost.getName()).isEqualTo(mockPost.getName()); assertThat(returnPost.getContent()).isEqualTo(mockPost.getContent()); assertThat(returnPost.getWriteTime()).isEqualTo(mockPost.getWriteTime());
verify(postRepository).save(any()); } }
|