
연습삼아 만들었던 게시판 api 에 테스트 코드를 적용해보기로 했다.
간단하게 posts, comments 두 개의 테이블을 가지고 진행한 작업이고, 각 Service 에 테스트를 했다.
package com.example.spring_board.service;
import com.example.spring_board.dto.post.CreatePostReqDto;
import com.example.spring_board.dto.post.PostReqDto;
import com.example.spring_board.dto.post.PostResDto;
import com.example.spring_board.repository.post.PostRepo;
import com.example.spring_board.service.post.PostService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.Page;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.server.ResponseStatusException;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;
@SpringBootTest
@Transactional
public class PostServiceTest {
@Autowired
PostService postService;
@Autowired
PostRepo postRepo;
@Test
public void 게시글생성조회() {
CreatePostReqDto post = new CreatePostReqDto("0000", "test", "testContents");
Long saveId = postService.createPost(post).getId();
PostResDto findPost = postService.findPostById(saveId);
assertThat(post.getContents()).isEqualTo(findPost.getContents());
}
@Test
public void 게시글전체조회() {
for (int i = 0; i < 100; i++) {
CreatePostReqDto post = new CreatePostReqDto("0000", "test" + i, "testCon" + i);
postService.createPost(post);
}
Page<PostResDto> pagePosts = postService.findAllPosts(0, 10);
assertThat(pagePosts.getTotalElements()).isEqualTo(100L);
assertThat(pagePosts.getTotalPages()).isEqualTo(10);
// 게시글 항목 조회 type
List<PostResDto> postList = pagePosts.getContent();
PostResDto firstPost = postList.get(0); // 첫 번째 게시글 가져오기
assertThat(firstPost.getTitle()).isEqualTo("test99"); // 첫 번째 글의 제목 검증
assertThat(firstPost.getContents()).isEqualTo("testCon99"); // 첫 번째 글의 내용 검증
}
@Test
public void 게시글수정() {
CreatePostReqDto post = new CreatePostReqDto("0000", "test", "testContents");
PostResDto created = postService.createPost(post);
PostReqDto updatePostReq = new PostReqDto("patchTest", "0000", "patchTestContents");
PostResDto updatedPost = postService.updatePost(created.getId(), updatePostReq);
assertThat(updatedPost.getTitle()).isEqualTo("patchTest");
assertThat(updatedPost.getContents()).isEqualTo("patchTestContents");
}
@Test
public void patchAndDeleteException_invalidPassword() {
CreatePostReqDto post = new CreatePostReqDto("0000", "test", "testContents");
PostResDto created = postService.createPost(post);
PostReqDto updatePostReq = new PostReqDto("patchTest", "1000", "patchTestContents");
PostReqDto deletePostReq = new PostReqDto(null, "1000", null);
ResponseStatusException updateErr = assertThrows(ResponseStatusException.class, () -> postService.updatePost(created.getId(), updatePostReq));
ResponseStatusException deleteErr = assertThrows(ResponseStatusException.class, () -> postService.deletePost(created.getId(), deletePostReq));
assertThat(updateErr.getReason()).isEqualTo("invalid password");
assertThat(deleteErr.getReason()).isEqualTo("invalid password");
}
@Test
public void 게시글삭제() {
CreatePostReqDto post = new CreatePostReqDto("0000", "test", "testContents");
PostResDto created = postService.createPost(post);
PostReqDto deletePostReq = new PostReqDto(null, "0000", null);
postService.deletePost(created.getId(), deletePostReq);
ResponseStatusException e = assertThrows(ResponseStatusException.class, () -> postService.findPostById(created.getId()));
assertThat(e.getReason()).isEqualTo("no post having id " + created.getId());
}
@Test
public void 게시글좋아요() {
CreatePostReqDto newPost = new CreatePostReqDto("0000", "test", "testContents");
PostResDto post = postService.createPost(newPost);
for (int i = 0; i < 100; i++) {
post = postService.addPostLike(post.getId());
}
assertThat(post.getLikes()).isEqualTo(100);
}
@Test
public void 없는id_get_update_delete() {
CreatePostReqDto newPost = new CreatePostReqDto("0000", "test", "testContents");
PostResDto post = postService.createPost(newPost);
PostReqDto updatePostReq = new PostReqDto("patchTest", "0000", "patchTestContents");
ResponseStatusException getErr = assertThrows(ResponseStatusException.class, () -> postService.findPostById(post.getId() + 1));
ResponseStatusException updateErr = assertThrows(ResponseStatusException.class, () -> postService.updatePost(post.getId() + 1, updatePostReq));
ResponseStatusException deleteErr = assertThrows(ResponseStatusException.class, () -> postService.deletePost(post.getId() + 1, updatePostReq));
assertThat(getErr.getReason()).isEqualTo("no post having id " + (post.getId() + 1));
assertThat(updateErr.getReason()).isEqualTo("no post having id " + (post.getId() + 1));
assertThat(deleteErr.getReason()).isEqualTo("no post having id " + (post.getId() + 1));
}
}
게시글생성조회 -> post 를 생성한 후 받아온 id 로 게시글을 조회해 내용의 일치 여부를 판단
게시글전체조회 -> 반복문을 사용하여 100개의 post 를 추가한 후 받아온 결과에서 totalElements, totalPage, 첫 번째 글의 내용을 검증
게시글수정 -> post 생성 후 update 진행하고 다시 받아와 값 비교
patchAndDeleteException_invalidPassword -> 틀린 비밀번호로 delete, update 진행 후 exception 잡아서 getReason 비교
게시글삭제 -> post 생성 후 delete 진행하고 해당 id 값이 조회되는지 확인
게시글좋아요 -> post 생성 후 반복문 사용하여 100번 좋아요 요청 호출하고 값 확인
없는id_get_update_delete() -> post 생성하고 받아온 id 와 다른 값을 사용해 조회 진행 후 getReason 확인
package com.example.spring_board.service;
import com.example.spring_board.dto.comment.CommentReqDto;
import com.example.spring_board.dto.comment.CommentResDto;
import com.example.spring_board.dto.comment.CreateCommentReqDto;
import com.example.spring_board.dto.post.CreatePostReqDto;
import com.example.spring_board.service.comment.CommentService;
import com.example.spring_board.service.post.PostService;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.server.ResponseStatusException;
import java.util.List;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;
@Transactional
@SpringBootTest
public class CommentServiceTest {
@Autowired
private CommentService commentService;
@Autowired
private PostService postService;
private Long postId;
@BeforeEach
public void createPost() {
CreatePostReqDto post = new CreatePostReqDto("0000", "test", "testContents");
this.postId = postService.createPost(post).getId();
}
@Test
public void 댓글생성조회() {
CreateCommentReqDto createCommentReq = new CreateCommentReqDto("test", "0000", this.postId);
Long id = commentService.createComment(createCommentReq).getId();
Long commentId = commentService.findCommentById(id).getId();
assertThat(id).isEqualTo(commentId);
}
@Test
public void 게시글별댓글전체조회() {
for (int i = 0; i < 100; i++) {
CreateCommentReqDto createCommentReq = new CreateCommentReqDto("test" + i, "0000", this.postId);
commentService.createComment(createCommentReq);
}
List<CommentResDto> comments = postService.findAllCommentsByPostId(this.postId);
assertThat(comments.size()).isEqualTo(100);
assertThat(comments.get(0).getContents()).isEqualTo("test99");
}
@Test
public void 댓글수정() {
CreateCommentReqDto createCommentReq = new CreateCommentReqDto("test", "0000", this.postId);
CommentResDto created = commentService.createComment(createCommentReq);
CommentReqDto updateReq = new CommentReqDto("patchTestContents", "0000");
CommentResDto updated = commentService.updateComment(created.getId(), updateReq);
assertThat(updated.getContents()).isEqualTo("patchTestContents");
}
@Test
public void 댓글삭제() {
CreateCommentReqDto createCommentReq = new CreateCommentReqDto("test", "0000", this.postId);
CommentResDto created = commentService.createComment(createCommentReq);
CommentReqDto deleteReq = new CommentReqDto(null, "0000");
commentService.deleteComment(created.getId(), deleteReq);
ResponseStatusException e = assertThrows(ResponseStatusException.class, () -> commentService.findCommentById(created.getId()));
assertThat(e.getReason()).isEqualTo("no comment having id " + created.getId());
}
@Test
public void 댓글좋아요() {
CreateCommentReqDto createCommentReq = new CreateCommentReqDto("test", "0000", this.postId);
CommentResDto created = commentService.createComment(createCommentReq);
for (int i = 0; i < 100; i++) {
created = commentService.addCommentLike(created.getId());
}
assertThat(created.getLikes()).isEqualTo(100);
}
@Test
public void invalidPassword_update_delete() {
CreateCommentReqDto createCommentReq = new CreateCommentReqDto("test", "0000", this.postId);
CommentResDto created = commentService.createComment(createCommentReq);
CommentReqDto deleteReq = new CommentReqDto(null, "1000");
CommentReqDto updateReq = new CommentReqDto("patchTestContents", "1000");
ResponseStatusException updateErr = assertThrows(ResponseStatusException.class, () -> commentService.updateComment(created.getId(), updateReq));
ResponseStatusException deleteErr = assertThrows(ResponseStatusException.class, () -> commentService.deleteComment(created.getId(), deleteReq));
assertThat(updateErr.getReason()).isEqualTo("invalid password");
assertThat(deleteErr.getReason()).isEqualTo("invalid password");
}
@Test
public void 없는id() {
CreateCommentReqDto createCommentReq = new CreateCommentReqDto("test", "0000", this.postId);
CommentResDto created = commentService.createComment(createCommentReq);
ResponseStatusException e = assertThrows(ResponseStatusException.class, () -> commentService.findCommentById(created.getId() + 1));
assertThat(e.getReason()).isEqualTo("no comment having id " + (created.getId() + 1));
}
}
BeforeEach -> post.id 와 연결되는 DB 라 각 테스트 실행 전 createPost() 메서드 실행시켜 post 생성 후 id 필드에 할당
댓글생성조회 -> comment 생성 후 받아온 id 로 조회하고 일치여부 확인
게시글별댓글전체조회 -> 반복문 사용하여 comment 생성 후 size 와 첫 번째 값 일치 여부 확인
댓글수정 -> comment 생성 후 받아온 id 로 update 진행 후 내용 확인
댓글삭제 -> comment 생성 후 받아온 id 로 delete 진행 후 getReason 일치 여부 확인
댓글좋아요 -> comment 생성 후 반복문으로 좋아요 요청 보내고 조회 후 일치 여부 확인
invalidPassword_update_delete -> comment 생성 후 잘못된 비밀번호로 delete, update 진행하고 err getReason 일치 여부 확인
없는id -> comment 생성 후 받아온 id 와 다른 값을 사용해 조회 후 발생한 에러 getReason 일치 여부 확인
- service 테스트를 진행하며 service 메서드에 의존함 (예. createPost 를 테스트 하는 과정에서 findById 메서드를 사용해서 값을 조회)
- Transactional 을 사용해 DB 에 값이 남지는 않지만 AUTO_INCREMENT 된 id 값이 증가해있는 문제가 있음. MockDB 등을 사용해 해결할 수 있다.