본문으로 바로가기

목차

    0. 환경

    • m1 macbook
    • IntelliJ IDEA(m1) - 202102
    • java 11(AdoptOpenJDK-11.0.11)

    1. 통합 테스트 케이스 작성

    • hello/hellospring/service/MemberServiceIntegrationTest.java
    • 이전에 작성한 순수 jdbc H2DB 연동을 하여 기능이 잘 작동하는지 테스트해봅니다.
    • 이전까지는 순수 자바 코드 테스트를 했으나 DB Connection 정보라던지 스프링 부트가 가지고 있는 상황입니다. 따라서 @SpringBootTest를 활용해 스프링 컨테이너와 테스트를 함께 실행합니다.
    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
    public 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("이미 존재하는 회원입니다.");
        }
    }

    2. 핵심 어노테이션

    • @SpringBootTest
    • @Transactional

    2.1. @SpringBootTest

    • 통합 테스트를 제공하는 기본적인 스프링 부트 테스트 어노테이션입니다.
    • 스프링 컨테이너와 테스트를 함께 실행 가능해져 스프링 컨테이너에게 의존성 주입을 쉽게 받을 수 있습니다.
    @Autowired MemberService memberService;
    @Autowired MemberRepository memberRepository;

    2.2. @Transactional

    • 테스트 케이스에 사용할 경우 테스트 시작 전 트랜잭션을 시작하고, 테스트 완료 후에 항상 롤백합니다.
    • DB에 데이터가 남지 않습니다.
      • 테스트는 반복이 가능해야 하는데 이를 충족시켜줍니다.
    • 일반 서비스 코드 등에 사용 시에는 롤백이 아니고 정상적으로 커밋됩니다. 테스트 케이스에서만 항상 롤백 적용됩니다.

    2.3. 트랜잭션 상태

    트랜잭션

    3. 단위 테스트 vs 통합 테스트

    • 가급적이면 순수한 단위 테스트가 좋은 테스트일 확률이 높습니다.
    • 따라서 스프링 컨테이너 없이 테스트할 수 있을 정도로 훈련을 해야 합니다.
    • 진짜 좋은 테스트는 단위 테스트를 잘 만드는 것입니다.