울음참고 개발공부
728x90

단위 테스트

 

[ 정의 ]

 

단위 테스트는 앱의 작은 단위(일반적으로 메서드)를 사용하여 코드의 나머지 부분에서 격리하고 예상대로 작동하는지 확인한다.

 

스프링 컨테이너 없이 하는 순수한 테스트라고 할 수도 있다.

 

[ 예시 ]

 

회원가입을 위한 테스르를 예시로 살펴보자 

class MemberServiceIntegrationTest {

    MemberService memberService;
    MemoryMemberRepository memberRepository;

    @BeforeEach
    public void beforeEach() {
        memberRepository = new MemoryMemberRepository();
        memberService = new MemberService(memberRepository);
    }

    @AfterEach
    public void afterEach() {
        memberRepository.clearStore();
    }

    @Test
    void 회원가입() {
        //given
        Member member = new Member();
        member.setName("hello");

        //when
        Long saveId = memberService.join(member);

        //then
        Member findMember = memberService.findOne(saveId).get();
        assertThat(member.getName()).isEqualTo(findMember.getName());
    }

    @Test
    public void 중복_회원_예외() {
        //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("이미 존재하는 회원입니다.");

        //then
    }
  }

 

해당 코드는 회원가입시 필요한 로직을 구현하는 테스트를 위해 작성된 테스트 코드이다.

 

save() 메서드는 회원등록을 위한 테스트인데, 여기서 테스트를 몇번 진행한다고 가정하자 

첫번째 테스트에서 "spring" 이 저장되었다면, 한번 더 진행한 테스트에서는 중복이 발생할 것이다.( 중복을 위한 로직을 구현한 상태)

 

그래서 실행시 마다 데이터를 비워줘야하는데, 이때 필요한 것이바로 @AfterEach 어노테이션에 해당하는 코드이다.

 

또한, 이렇게 작성된 테스트가 순수한 단위테스라 할 수있다. 

 

 

[ 장점 ]

 

단위 테스트의 경우 기본적으로 실행속도가 빠르고, 단위테스트를 잘 작성할 수록 좋은 테스트라고 한다.

그 이유는, 통합 테스트의 경우 테스트 설계가 잘못되었을 확률이 높아서라고 한다. 

 

 

통합 테스트

 

[ 정의 ]

 

통합 테스트는 애플리케이션의 모든 구성 요소가 예상대로 함께 작동하는지 확인하는 소프트웨어 테스트 유형이다.

 

스프링 컨테이너와 DB 를 이용하여 하는 테스트라고도 할 수 있다. 

 

[ 예시 ]

 

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

    @BeforeEach
    public void beforeEach() {
        memberRepository = new MemoryMemberRepository();
        memberService = new MemberService(memberRepository);
    }

    @Test
    void 회원가입() {
        //given
        Member member = new Member();
        member.setName("hello");

        //when
        Long saveId = memberService.join(member);

        //then
        Member findMember = memberService.findOne(saveId).get();
        assertThat(member.getName()).isEqualTo(findMember.getName());
    }

// 생략 

}

 

@SpringBootTest 

 - 스프링 컨테이너와 테스트를 실행하기 위한 어노테이션

 

스프링 컨테이너와 사용하기 위해 @Autowired 를 사용

( 테스트단이기 때문에 해당 클래스를 스프링에 @Controller 등으로 등록해두는 것이아닌 필드에서 주입받는 식(@Autowired 로) 으로 바로 사용한다 )

 

 

@Transactional 

해당 어노테이션을 사용하지 않는 경우에는 테스트 코드를 실행할 때마다 실제 DB 에 값이 들어가게 된다.

 

예를 들어, save() 메서드가 실행될 경우에 "spring" 이 계속 등록되어 다음 테스트 시에는 중복이 일어나는 것이다.

그렇다면 테스트시 마다 DB 에서 값을 지워주거나 "spring2" "spring3" 등으로 진행하여야 하는 걸까?

 

이럴 때 사용하기 위한 것이 해당 어노테이션이다. 

@Test 시 마다 실행되어 항상 롤백을 실행한다.

따라서 실제 DB 에 저장되지 않게하여 다음 테스트에 영향을 주지않는다. 

 

 

참고 ) 실제 테스트시에는 운영 DB 가 아닌 테스트 DB 나 로컬 DB 를 사용하여 테스트한다 

 

 

[ 출처 ]

인프런 - "스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술" (무료수업) 중 일부 

728x90
profile

울음참고 개발공부

@메각이

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!