Notice
Recent Posts
Recent Comments
관리 메뉴

Developer Gonie

[스프링 부트] 11. 회원 리포지토리 테스트 케이스 작성 본문

인프런 김영한님 강의/1 . 스프링 부트 입문

[스프링 부트] 11. 회원 리포지토리 테스트 케이스 작성

이대곤 2022. 6. 26. 17:52

MemoryMemberRepository 클래스 관련, 테스트 케이스 작성

* 테스트 케이스 작성이 필요한 이유

혼자 개발할 때는 괜찮은데 여러명에서 개발할 때, 혹은 코드가 몇만 라인을 넘어가면 테스트 코드 없이 개발하는게 거의 불가능하다고 한다. 물론 할 수 있지만 정말 문제가 많다는 말씀이다. 실무에서는 테스트를 빌드툴하고 묶어서 테스트 케이스를 통과하지 못하면 다음 단계로 못 넘어가게 막아버린다고 한다. 중요하니 꼭 '테스트' 관련해서 깊이있는 공부를 권장하심. 

 

아래서 한 방식은 구현 클래스를 작성하고 나서 테스트 케이스를 작성한 것인데, 테스트 주도개발 방식이라고 불리는 TDD는 테스트 케이스를 먼저 작성하고 이거에 문제 없이 작동하도록 구현 클래스를 작성하는 것이다. 이런게 있다는 것 정도는 알아두자.

지금까지는 개발한 기능을 실행해서 테스트 할 때, 자바의 main 메서드를 통해서 실행하거나 웹 어플리케이션의 컨트롤러를 통해서 해당 기능을 실행해 왔을 것이다. 하지만, 이러한 방법은 실행하는데 오래 걸리고, 반복 실행하기 어려우며, 여러 테스트를 한 번에 실행하기 어렵다. 자바는 JUnit이라는 프레임워크로 테스트 코드를 만들고, 이 코드를 실행해서 이 문제를 해결한다.

 

* 테스트 케이스 작성 방법

1. 테스트 케이스는 테스트클래스 내에서 메소드 단위로 구현되는데, test 폴더 안에서 아무 클래스를 만들고
    이 클래스 내부에서 main 폴더에서 만들어놓은 클래스들의 멤버함수들을 테스트할 메소드들을 작성한다.

    주의!! 이때 메소드별로 @Test 어노테이션을 붙여줘야 한다. (이 때 Test는 org.junit.jupiter.api의 것을 선택)

   @Test 어노테이션이 없으면 무슨일이 발생하는가? 테스트를 실행해도 해당 메소드가 실행에 포함되지 않는다.

 

2. 테스트 실행시 실행되는 메소드의 실행 순서는 보장이 안되도록 설계되어 있어 순서에 의존되게 코딩하면 안된다.
    이 의미가 무엇이냐? 테스트 실행중 하나의 메소드 실행 종료시 마다 공용 변수를 초기상태로 돌려줘야 한다는 것이다.

    이는 @AffterEach 어노테이션을 붙여주어 콜백메소드를 정의하여 처리해 줄 수 있는데

    콜백 메서드의 내용을 공용 변수를 초기상태로 돌려주도록 하면 된다.

 

* 테스트 케이스 실행 방법

   test 폴더 안에서 작성한 테스트 클래스를 오른쪽 마우스로 클릭하여 모든 테스트 메소드를 단번에 실행하거나,

   코드 왼쪽 편에 생겨난 실행버튼을 통해 메소드 단위별로 개별적인 실행이 가능하다.

   콘솔에서도 실행이 가능하다고 함.

1. test /hello.hellospring 패키지 아래에 repository 패키지 생성

2. 위 패키지 내에서 MemoryMemberRepositoryTest 클래스 생성

package hello.hellospring.repository;

import hello.hellospring.domain.Member;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;

import java.util.List;

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

class MemoryMemberRepositoryTest {
    MemoryMemberRepository repository = new MemoryMemberRepository();

    @AfterEach // 하나의 테스트 메서드의 동작이 끝날 때 마다 자동으로 불리게 되는 콜백 메서드 정의
    public void afterEach(){ // 메서드 이름은 아무거나로 해도 됨
        repository.clearStore();
    }

    @Test // MemoryMemberRepository 클래스의 save 메서드 테스트
    public void save(){
        // 저장할 객체 만들어서 저장
        Member member = new Member();
        member.setName("spring");
        repository.save(member);

        // 저장한걸 다시 받아온 객체
        Member result = repository.findById(member.getId()).get(); // get()을 쓴 이유는 Optional 을 벗겨내기 위함

        // 위의 두 객체 비교
        assertThat(member).isEqualTo(result);
    }

    // 1) 콘솔에서 직접 출력해서 확인하는 방법, 달라도 같아도 그냥 텍스트로 아래의 결과가 출력되기만 함.
    // System.out.println("result = " + (result == null)); // 다른 경우
    // System.out.println("result = " + (result == member)); // 같은 경우

    // 2) org.junit.jupiter.api 의 Assertions 를 이용한 방법, 두 객체가 같으면 아무것도 안뜨나 둘이 다르면 에러문을 띄움
    // Assertions.assertEquals(result, null); // 다른 경우
    // Assertions.assertEquals(result, member); // 같은 경우

    // 3*) org.assertj.core.api 의 Assertions 를 이용한 방법, 위와 문법만 다른데 최근에 자주 사용됨.
    // Assertions.assertThat(member).isEqualTo(null); // 다른 경우
    // Assertions.assertThat(member).isEqualTo(result); // 같은 경우
    // Alt + Enter로 Add on demand static import for 'org.assertj.core.api.Assertions' 해주면
    // 위 import에 해당 클래스가 import되어 assertThat().isEqualTo() 만으로도 메서드 사용이 가능하다.
    // assertThat(member).isEqualTo(result);

    @Test // MemoryMemberRepository 클래스의 findByName 메서드 테스트
    public void findByName(){
        // 저장할 객체 만들어서 저장
        Member member1 = new Member();
        member1.setName("spring1");

        Member member2 = new Member();
        member2.setName("spring2");

        repository.save(member1);
        repository.save(member2);

        // 저장한 것 중에서 하나만 다시 받아온 객체
        Member result = repository.findByName("spring1").get();

        // 위의 두 객체 비교
        assertThat(result).isEqualTo(member1);
    }

    @Test // MemoryMemberRepository 클래스의 findAll 메서드 테스트
    public void findAll(){
        Member member1 = new Member();
        member1.setName("spring1");

        Member member2 = new Member();
        member2.setName("spring2");

        repository.save(member1);
        repository.save(member2);

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

        assertThat(result.size()).isEqualTo(2);
    }
}
Comments