게시판 구현(3.0) - 댓글 Junit Test

김지민·2023년 6월 28일

spring Boot

목록 보기
4/9

댓글 기능

entity class 설계

// @NoArgsConstructor, @Getter는 entity 클래스에서 필수 요소
@NoArgsConstructor
@Getter
// 필드 post를 제외하고 toString을 만들어 줌
@ToString(exclude = { "post" })

@Entity
@Table(name = "REPLIES")
@SequenceGenerator(name = "REPLIES_SEQ_GEN", sequenceName = "REPLIES_SEQ", allocationSize = 1)
public class Reply extends BaseTimeEntity {

    @Id
    @GeneratedValue(generator = "REPLIES_SEQ_GEN", strategy = GenerationType.SEQUENCE)
    private Long id; // Primary Key

    // 관계 애너테이션 설명:
    // 클래스를 기준으로 생각
    // 여러개의 reply가 한 개의 post에 달릴 수 있음.
    // To 앞에 있는게 reply 클래스
    // Many: Reply 클래스
    // One: Post 클래스

    // fetch: 데이터를 가지고 오는 행위
    // fetch의 타입:
    // EAGER(기본값): 즉시 로딩, LAZY: 지연 로딩
    @ManyToOne(fetch = FetchType.LAZY)
    private Post post; // Foreign Key, 관계를 맺고 있는 entity

    @Column(nullable = false) // Not Null
    private String replyText; // 댓글 내용

    @Column(nullable = false)
    private String writer; // 댓글 작성자

}

reply id 검색

해당 클래스에 대하여 Junit Test를 실행할 떄,

Junit Test

  // 댓글 번호로 검색하기
   // @Test
    public void testFindById() {
        
        // 11: integer type -> L 붙여야 함.
        // select * from replies where id = 11;
        //-> 다음 쿼리문이 아닌 이유:
        /*
         * entity 클래스에서 관계형 데이터 베이스에서 관계를 가지고 있다고 entity를 정의하면 기본적으로 join문장을 사용함.
         * (예) @ManyToOne
         */
       
        
        Reply reply =  replyRepository.findById(11L).orElseThrow();
        log.info(reply.toString());
       // log.info(reply.getPost().toString());
        
        /*
         * findById() 메서드는
         * reply entity에서 FetchType.EAGER를 사용한 경우에는 join 문장을 실행
         * FetchType.LAZY를 사용한 경우에는 단순 select 문장을 실행하고, 
         * Post 엔터티가 필요한 경우에 (나중에) join 문장이 실행됨.
         * 
         * 현업에서는 보통 FetchType.LAZY을 사용.
         */
    }
  1. @ToString(exclude = { "post" })가 아닌
    @ToString 일경우 결과

    결과

  2. @ManyToOne 일 경우 결과

    @ManyToOne
       private Post post; // Foreign Key, 관계를 맺고 있는 entity

    결과

  3. @ManyToOne(fetch = FetchType.LAZY) 일 경우

    @ManyToOne(fetch = FetchType.LAZY)
       private Post post; // Foreign Key, 관계를 맺고 있는 entity

결과

+ 아래 코드 실행시, Junit Test에서 에러 발생한 이유:

 log.info(reply.getPost().toString());

join 없이 검색 후 entity 매니저가 닫아버렸기에 더 이상의 테스트 불가

@Transactional의 경우는 닫아버리지 않고 또 문장이 있을 경우 entity 매니저가 실행함.
그래서 fetch = FetchType.LAZY의 경우 필요한 경우((예) getter())에 join을 함.

reply postId 검색

ReplyRepository

package com.itwill.spring4.repository.reply;

import java.util.List;

import org.springframework.data.jpa.repository.JpaRepository;

import com.itwill.spring4.repository.post.Post;

public interface ReplyRepository extends JpaRepository<Reply, Long> {
    
    // Post (id)로 검색하기:
    List<Reply> findByPost(Post post);
    
}

Junit Test

 @Test
   public void testFindByPost() {
       // 포스트 아이디로 포스트 1개를 검색:
       Post post = postRepository.findById(7L).orElseThrow();
       
       // 해당 포스트에 달린 모든 댓글 검색:
       List<Reply> list = replyRepository.findByPost(post);
       for(Reply r : list) {
           log.info(r.toString());
       }
   }

결과

profile
한 단계씩 차근차근

0개의 댓글