6. SpringBoot 입문 - Spring DB 접근 기술 - 통합 테스트

2021. 5. 26. 16:04WEB Dev./Spring Boot 입문

  1. H2 데이터베이스 설치
  2. 순수 JDBC
  3. Spring 통합 테스트
  4. Spring JdbcTemplate
  5. JPA
  6. Spring Data JPA (JPA를 더 편리하게)

3. Spring 통합 테스트

Spring을 올리고 DB까지 연결해서 동작하는 테스트를 해보겠습니다.

 

기존에 해온 테스트는 순수Java 코드로 작성한 테스트였지만 이젠 Spring을 올린 상태에서 테스트해야 하므로..

@SpringBootTest 어노테이션을 추가해줍니다.

 

/test/java/hello.hellospring/service/MemberServiceIntegrationTest

package hello.hellospring.service;

import hello.hellospring.domain.Member;
import hello.hellospring.repository.MemberRepository;
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 static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;

@SpringBootTest
@Transactional
class MemberServiceIntegrationTest {
    
    @Autowired MemberService memberService;
    @Autowired MemberRepository memberRepository;

    @Test
    public void 회원가입() throws Exception {
    
        //Given
        Member member = new Member(); member.setName("hello");
    
        //When
        Long saveId = memberService.join(member);
    
        //Then
        Member findMember = memberRepository.findById(saveId).get();
        assertEquals(member.getName(), findMember.getName());
    }

    @Test
    public void 중복_회원_예외() throws Exception {
    
        //Given
        Member member1 = new Member(); 
        member1.setName("spring");
        
        Member member2 = new Member(); 
        member2.setName("spring");

        //When
        memberService.join(member1);

        IllegalStateException e = assertThrows(IllegalStateException.class, 
            () -> memberService.join(member2));//예외가 발생해야 한다.
        
        assertThat(e.getMessage()).isEqualTo("이미 존재하는 회원입니다.");
    }
}

 

@SpringBootTest = 스프링 컨테이너와 테스트를 함께 실햅합니다.

 

테스트 케이스를 만들 때는 제일 편한 방법을 사용하면 좋습니다. 테스트를 하고 끝이므로 DI도 필드 기반으로 하는게 편합니다.

테스트는 반복할 수 있어야 합니다. 하지만 이미 값이 저장되면 다음 테스트에서는 중복이 발생하므로 오류가 발생합니다. 매번 디비의 내용을 테스트가 끝날때마다 삭제하는 것도 무리가 있습니다.

@Transactional 어노테이션을 사용하면 테스트를 실행할 때 Transaction을 먼저 실행해 쿼리에 맞는 데이터를 저장하고 테스트가 끝날 때 Rollback 해줍니다.

 

스프링 통합 테스트보다 순수한 Java 코드로 작성한 단위테스트가 성능면에서 훨씬 좋습니다. 따라서 스프링 컨테이너 없이 테스트 케이스를 만들 수 있도록 하는 것이 중요합니다.