게시글에 담을 정보로는 게시글번호, 카테고리, 제목, 내용, 작성자, 등록일, 작성일 이렇게 총 6가지로 구현할 예정입니다.
Post Entity
@Entity
@Getter
@NoArgsConstructor
public class Post extends BaseEntity {
@Id
@Column(name = "post_id")
@GeneratedValue(strategy = GenerationType.SEQUENCE)
private Long id;
private String category;
private String title;
private String content;
@NonNull
@Column(name = "create_by")
private String author;
@Builder
public Post(String category, String title, String content, String author) {
this.category = category;
this.title = title;
this.content = content;
this.author = author;
}
public void updatePost(PostDto postDto) {
this.category = postDto.getCategory();
this.title = postDto.getTitle();
this.content = postDto.getContent();
}
}
Base Entity
@EntityListeners(AuditingEntityListener.class)
@MappedSuperclass
@Getter
public class BaseEntity {
@CreatedDate
private LocalDateTime createAt;
@LastModifiedDate
private LocalDateTime updateAt;
}
등록일, 작성일은 같은 경우 나중에 공통으로 사용할 생각으로 BaseEntity로 관리하기로 했습니다.
이번 게시판 생성 프로젝트에선 대부분의 기능들은 테스트를 진행할 계획!
TestCode
class PostTest {
@DisplayName("게시글 수정")
@Test
void updatePost() {
//given
Post post = Post.builder()
.category("SpringBoot")
.title("게시글 생성")
.content("게시글내용")
.author("user1")
.build();
//when
PostDto updatePostDto = PostDto.builder()
.category("Spring")
.title("게시글 수정")
.content("게시글 내용 수정")
.build();
post.updatePost(updatePostDto);
//then
assertThat(post.getContent()).isEqualTo("게시글 내용 수정");
}
}
post 객체 생성 및 게시글 수정 테스트를 진헹하였으니 이제 JPA를 이용한 PostRepository 인터페이스 생성 및 테스트 진행하겠습니다.
PostRepository
@Repository
public interface PostRepository extends JpaRepository<Post,Long>, QuerydslPredicateExecutor<Post>, CustomPostRepository {
}
findAll() : POST 테이블에서 레코드 전체목록을 조회
findById(id) : POST 테이블에서 기본키 값이 id인 레코드를 조회
하며 Optional<Post>타입의 객체 리턴
exist(id): POST 테이블에서 id에 해당하는 레코드 여부에 따라 true/false 리턴
save(post) : Post객체를 POST 테이블에 저장
PostRepository 테스트는 아래와 같이 진행하였습니
PostRepositoryTest
@DataJpaTest
class PostRepositoryTest {
@Autowired
PostRepository postRepository;
@Nested
@DisplayName("게시글 찾기")
class findPostTest {
@DisplayName("성공")
@Test
void success() {
//given
Post post = Post.builder()
.category("SpringBoot")
.title("게시글 생성")
.content("게시글내용")
.author("user1")
.build();
postRepository.save(post);
//when
Post findPost = postRepository.findById(post.getId()).get();
//then
assertThat(findPost.getId()).isEqualTo(post.getId());
}
@DisplayName("결과 없음")
@Test
void isEmpty() {
//given
//when
boolean result = postRepository.existsById(99L);
//then
assertThat(result).isFalse();
}
}
@Nested
@DisplayName("게시글 목록 조회")
class getPosts {
@DisplayName("성공")
@Test
void success() {
//given
for (int i = 0; i < 20; i++) {
Post post = Post.builder()
.category("카테고리" +i/5)
.title("게시글 생성"+i)
.content("게시글내용"+i)
.author("user")
.build();
postRepository.save(post);
}
String keyword = "카테고리0";
int page = 0;
int size = 10;
Pageable pageable = PageRequest.of(page, size);
//when
List<PostDto> result = postRepository.getPosts(keyword, pageable);
//then
assertThat(result.size()).isNotEqualTo(size);
assertThat(result.size()).isEqualTo(5);
}
@DisplayName("성공 - 카테고리 미입력")
@Test
void successCategoryIsEmpty() {
//given
for (int i = 0; i < 20; i++) {
Post post = Post.builder()
.category("카테고리" +i/5)
.title("게시글 생성"+i)
.content("게시글내용"+i)
.author("user")
.build();
postRepository.save(post);
}
String keyword = "";
int page = 0;
int size = 10;
Pageable pageable = PageRequest.of(page, size);
//when
List<PostDto> result = postRepository.getPosts(keyword, pageable);
//then
assertThat(result.size()).isEqualTo(size);
}
@DisplayName("실패 - 등록된 게시글이 존재 하지 않음")
@Test
void isEmpty() {
//given
String keyword = "카테고리0";
int page = 0;
int size = 10;
Pageable pageable = PageRequest.of(page, size);
//when
List<PostDto> result = postRepository.getPosts(keyword, pageable);
//then
assertThat(result).isEmpty();
}
@DisplayName("실패 - 해당 카테고리에는 게시글이 없음")
@Test
void invalidCategory() {
//given
for (int i = 0; i < 20; i++) {
Post post = Post.builder()
.category("카테고리" +i/5)
.title("게시글 생성"+i)
.content("게시글내용"+i)
.author("user")
.build();
postRepository.save(post);
}
//when
String keyword = "카테고리99";
int page = 0;
int size = 10;
Pageable pageable = PageRequest.of(page, size);
List<PostDto> result = postRepository.getPosts(keyword, pageable);
//then
assertThat(result).isEmpty();
}
}
}
@DataJpaTest 란?
JPA에 관련된 요소들만 테스트하기 위한 어노테이션으로 JPA 테스트에 관련된 설정들만 적용해줍니다.
메모리상에 내부데이터베이스를 생성하고 @Entity 클래스들을 등록하고 JPA Repository 설정들을 해주며, 각 테스트가 완료되면 관련한 설정들은 롤백됩니다.
@Nested
여러 테스트 그룹간의 관계를 표현할 수 있고 계층적으로 나타낼떄 사용하며, 정적클래스가 아닌 Inner Class에서만 사용 가능한 어노테이션입니다.