Zayson
A to Zayson!
Zayson
전체 방문자
오늘
어제
  • 분류 전체보기 (132)
    • Computer Science (20)
      • Network (4)
      • DB (12)
      • OS (4)
    • Algorithm (32)
      • 완전탐색(Brute-Force) (3)
      • 그리디(Greedy) (6)
      • 투포인터(Two-Pointer) (1)
      • 그래프(Graph) (5)
      • BFS & DFS (9)
      • 구현, 시뮬레이션(Implementation) (5)
      • 다이나믹 프로그래밍(DP) (3)
    • Backend (51)
      • Spring Boot (19)
      • JPA (16)
      • Kafka (2)
      • Java (13)
      • Kotlin (1)
    • DevOps (1)
      • Jenkins (5)
      • Oracle Cloud Infrastructure (1)
      • Kubernetes & Docker (1)
    • Trouble Shooting (3)
      • JPA (1)
      • Spring Boot (2)
    • 회고 (5)
      • 엔빵 프로젝트 포스트 로드맵 (1)
      • 2022년 (4)
    • Kafka (7)
      • Kafka (5)
      • Kafka Connect (2)
    • 기술 서적 (6)
      • 데이터 중심 애플리케이션 설계 (3)
      • 개발자가 반드시 정복해야할 객체 지향과 디자인 패턴 (2)
      • 가상 면접 사례로 배우는 대규모 시스템 설계 기초 (1)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

인기 글

태그

  • BFS
  • Kafka Connect
  • Java
  • 그리디
  • SpringBoot
  • 라이브스터디
  • kafka
  • 관계형 데이터베이스 실전 입문
  • Computer science
  • 엔빵프로젝트
  • 나 혼자 스프링부트!
  • 프로그래머스
  • 완전탐색
  • 백준
  • 구현
  • dfs
  • CS
  • JPA
  • Backend
  • spring boot

최근 글

티스토리

hELLO · Designed By 정상우.
Zayson

A to Zayson!

Repository 단위 테스트
Backend/Spring Boot

Repository 단위 테스트

2022. 7. 15. 00:11

@DataJpaTest와 @AutoConfigureTestDatabase를 이용해 Repository 메서드를 단위 테스트해보자.

@DataJpaTest

기본적으로 JPA 관련 설정들을 로드한다. 기본적으로 인메모리 테스트 데이터베이스를 이용해 실제 데이터베이스를 이용하지 않고 사용하는 것이 가능하다.

 

또한, @Tranasactional을 가지고 있기 때문에 테스트가 진행된 이후 자동으로 롤백하는 것이 가능하다.

 

@AutoConfigureTestDatabase

애노테이션 뜻 그대로 테스트 데이터베이스의 구성정보를 자동으로 설정해주는 애노테이션이다. 이 또한, @DataJpaTest에 가지고 있다.

 

위에서 기본적으로 인메모리 테스트 데이터베이스를 이용한다고 한 부분이 @AutoConfigureTestDatabase의 기본 내장 DB 커넥션이 H2, HSQLDB와 같이 인메모리 DB로 되어있기 때문이다.

 

이번 테스트 코드에서는 실제 Database를 이용해서 테스트하기 위해서 Replace.NONE을 설정해서 코드를 작성했다.

 

Repository

테스트 코드를 작성할 Repository를 확인해보자.

@Repository
public interface EventRepository extends JpaRepository<Event, Long> {
    // 이벤트 조회
    Event findByEventId(Long eventId);

    // 이벤트 저장
    Event save(Event event);

    // 이벤트 삭제
    void deleteByEventId(Long eventId);

    // 이벤트 리스트 조회(페이징)
    @Query("SELECT e FROM Event e WHERE e.eventId < :eventId ORDER BY e.eventId DESC")
    Slice<Event> findEventList(@Param("eventId") Long eventId, Pageable pageable);
}

테스트 코드

TestEntityManager를 이용해서 persis, find, flush와 같이 JPA의 실제 메서드를 테스트할 수 도 있다.

 

레포지토리 테스트 코드를 작성하는 도중 실제 DB를 이용하다 보니 저장 후 Auto Increment로 인한 엔티티의 Id를 가져오는 부분이 EntityManager를 이용하면 persist하고 가져올 수가 없었어서 아쉬운 대로 Repository에 저장한 save메서드를 사용해 테스트 코드를 작성했다.

 

Given(테스트 위한 사전 조건 및 Mocking 할 영역) , When(테스트를 할 영역), Then(테스트 이후 예상 결과와 실제 결과를 확인하는 영역)으로 구분 짓고 그에 맞는 코드를 작성했다.

@DataJpaTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
class EventRepositoryTest {
    @Autowired
    private EventRepository eventRepository;

    @Autowired
    private TestEntityManager em;

		// TestEntityManager를 이용해 테스트
    @Test
    @DisplayName("이벤트 레포지토리 : 이벤트 조회")
    void 이벤트조_조회하기() {
        // given
        Event event = testEventBuilder();
        em.persist(event);

        // when
        Event findEvent = em.find(Event.class, event.getEventId());

        // then
        assertThat(event.getTitle()).isEqualTo(findEvent.getTitle());
    }

		// 실제 데이터베이스를 이용하는 경우 Auto Increment가 이미 데이터베이스에 적용되어 있기 때문에 
    @Test
    @DisplayName("이벤트 레포지토리 : 이벤트 조회")
    void 이벤트_조회() {
        // given
        Event savedEvent = eventRepository.save(testEventBuilder());

        // when
        Event findEvent = eventRepository.findByEventId(savedEvent.getEventId());

        // then
        assertThat(savedEvent.getEventId()).isEqualTo(findEvent.getEventId());
        assertThat(savedEvent.getTitle()).isEqualTo(findEvent.getTitle());
        assertThat(savedEvent.getEventDetail()).isEqualTo(findEvent.getEventDetail());
    }

    @Test
    @DisplayName("이벤트 레포지토리 : 이벤트 등록")
    void 이벤트_등록() {
        // given
        Event event = testEventBuilder();

        // when
        Event savedEvent = eventRepository.save(event);

        // then
        assertThat(savedEvent.getTitle()).isEqualTo(event.getTitle());
        assertThat(savedEvent.getEventDetail()).isEqualTo(event.getEventDetail());
    }

    @Test
    @DisplayName("이벤트 레포지토리 : 이벤트 삭제")
    void 이벤트_삭제() {
        // given
        Event savedEvent = eventRepository.save(testEventBuilder());

        // when
        eventRepository.deleteByEventId(savedEvent.getEventId());

        // then
        Event findEvent = eventRepository.findByEventId(savedEvent.getEventId());
        assertThat(findEvent).isNull();
    }

    @Test
    @DisplayName("이벤트 레포지토리 : 이벤트 리스트 조회")
    void 이벤트_리스트_조회() {
        // given
        eventRepository.save(testEventBuilder());
        eventRepository.save(testEventBuilder());
        eventRepository.save(testEventBuilder());

        // when
        Slice<Event> findEventList = eventRepository.findEventList(10000L, PageRequest.of(0, 2));

        // then
        assertThat(findEventList.getSize()).isEqualTo(2);

    }

		// 이벤트 엔티티 생성
    private static Event testEventBuilder() {
        return Event.builder()
                .eventId(1L)
                .title("title")
                .eventDetail("eventDetail")
                .regYmd(LocalDateTime.now())
                .eventStart(LocalDate.now())
                .eventEnd(LocalDate.now().plusWeeks(1))
                .build();
    }

}

테스트가 모두 성공되는 것을 확인할 수 있다.

반응형
저작자표시 비영리 변경금지 (새창열림)

'Backend > Spring Boot' 카테고리의 다른 글

[API 고급] 컬렉션 조회 최적화  (0) 2022.07.12
[API 개발 고급] 지연 로딩과 조회 성능 최적화  (0) 2022.07.07
API 개발 기본 간단 정리  (0) 2022.07.07
도메인 개발 팁 간단 정리  (0) 2022.07.05
RestTemplate  (0) 2022.07.01
    'Backend/Spring Boot' 카테고리의 다른 글
    • [API 고급] 컬렉션 조회 최적화
    • [API 개발 고급] 지연 로딩과 조회 성능 최적화
    • API 개발 기본 간단 정리
    • 도메인 개발 팁 간단 정리
    Zayson
    Zayson
    공부한 내용을 정리하는 공간

    티스토리툴바