Spring 사용하기 (Coupon_check 백엔드(2) - 테스트)

김태훈·2022년 12월 27일
0

Spring_CouponCheck

목록 보기
5/14

개발에 있어서 테스트 코드는 매우 중요한 역할을 한다. 테스트 코드가 없다면, main 메서드를 일일이 실행하거나, 컨트롤러를 통해 실행해야 하는데 이렇게 되면 반복적으로 실행하기에 너무 귀찮고 힘든 일이다. 따라서 이를 자동화 해주는 것이 필요하겠다.

1. 테스트 코드 만들어 보기

이전 블로그에서, 함수를 실행하는 main 디렉토리와 test 디렉토리가 프로젝트 안에 나뉘어져 있는 것이 Spring의 설정이라고 말한 적이 있다. 지금은 테스트 코드를 작성해야 하므로, 당연히 test 디렉토리 안에서 작업이 이루어져야겠다.
보통 테스트코드를 작성하는 파일의 이름은 main 메서드에서 실행하는 파일의 이름뒤에 Test만 붙여서 작명한다.

  • 기본 골자
package repository;

import Goat.CouponCheck.repository.MemoryRepository;
import hello.hellospring.domain.Member;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

public class MemoryRepositoryTest {
    MemoryRepository repository = new MemoryRepository();

    @Test
    public void save(){
        hello.hellospring.domain.Member member = new Member();
        member.setName("goat");

        repository.saveMember(member);
        Member result = repository.findById(member.getId()).get();

        Assertions.assertEquals(member,result);
        //혹은 다음 코드로 작성하기도 한다. 아래 코드로 받아들일것.
        Assertions.assertThat(member).isEqualTo(result); //이때 불러오는 라이브러리는 assertj에서 불러와야함.
        //이 때, Assertions의 option (alt + enter) 를 보면 static import로 Assertions라이브러리를 불러오면, assertThat을 바로 쳐도 Assertions가 바로 불러와지기 때문에 더 간편히 만들 수 있다.
    }
}
  1. 테스트 코드에서는 보통 JUnit이라는 테스트코드를 작성해주는 프레임워크를 사용한다. 해당 프레임 워크를 사용하기 위해 "@Test"라는 Annotation 으로 불러와야만 한다.
  2. main메서드를 작성할때와 별 다를 것이 없다. 지금은 Repository에 Member가 잘 저장되는지 테스트 하는 코드로써, Member 객체를 만들고, Name만 set 시켜서(repository에 saveMember함수를 호출해서 인자로 member를 넣으면 알아서 id 와 couponNum이 설정되도록 했기 때문에) 저장시킨다.
  3. Member의 id (유일한 Primary Key 이므로)로 repository에서 해당 id를 가진 Member를 찾아온다. 이 때, findById의 반환형은 Optional이다. 하지만 get() 함수로 Member 반환형으로 꺼내올 수 있다는 것을 기억하자. (물론 test code에서만 괜찮음)
  4. 그 후, Assertions라는 라이브러리를 이용하여 기대값인 result가 member와 같은지 확인하는 과정을 거친다.
  5. 해당 test code를 run하면 초록불 혹은 빨간불이 뜨며 검증 과정을 거칠 수 있다.

전체 자바 코드

package repository;

import Goat.CouponCheck.repository.MemoryRepository;
import hello.hellospring.domain.Member;
import org.junit.jupiter.api.Test;

import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;

public class MemoryRepositoryTest {
    MemoryRepository repository = new MemoryRepository();

    @Test
    public void save(){
        hello.hellospring.domain.Member member = new Member();
        member.setName("goat");

        repository.saveMember(member);
        Member result = repository.findById(member.getId()).get();

        //Assertions.assertEquals(member,result);
        assertThat(member).isEqualTo(result);
    }

    @Test
    public void findByName(){
        Member member1 = new Member();
        member1.setName("hoon1");
        repository.saveMember(member1);

        Member member2 = new Member();
        member2.setName("hoon2");
        repository.saveMember(member2);

        Member result = repository.findByName("hoon1").get();

        assertThat(result).isEqualTo(member1);

    }

    @Test
    public void findAll(){
        Member member1 = new Member();
        member1.setName("hoon1");
        repository.saveMember(member1);

        Member member2 = new Member();
        member2.setName("hoon2");
        repository.saveMember(member2);

        List<Member> result = repository.findAll();

        assertThat(result.size()).isEqualTo(2);
    }
    
    @Test
    public void saveCoupon(){
        Coupon coupon = new Coupon();
        coupon.setNum();
        assertThat(coupon.getNum()).isEqualTo(9);
    }
    
    //coupon 0 개 예외 추가 테스트 작성할것.
    @Test
    public void saveOverCoupon(){
        Coupon coupon = new Coupon();
        for (int i = 0; i<11; i++){
            coupon.setNum();
        }
        assertThat(coupon.getNum()).isEqualTo(null);
    }
}

이 코드 전체를 실행하면 테스트코드가 실패했다고 뜬다. 왜 이럴까?
서로서로 test code를 실행할 때, 한 메서드에서 진행되었던 repository의 변화 과정이 다른 메서드에도 영향을 주기 때문이다. 이 때, 이를 방지하기 위해 test메서드하가 하나 종료되면, repository를 clear하는 과정이 있어야만 한다. = AfterEach Annotation 활용

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

다음과 같은 코드를 추가시킨다. 물론 repository, 즉, MemoryRepository class 에는 clearStore()함수가 정의가 되어야겠다. 해당 함수는 당연히 clear하는 코드가 작성 되어야 할 것이다. (github 코드 참조)

profile
기록하고, 공유합시다

0개의 댓글