본문 바로가기
Back-End/Spring Boot

회원 관리 예제 - 백엔드 개발 / 회원 리포지토리 테스트 케이스 작성

by 달의 조각 2022. 2. 23.
이 글은 김영한 님의 스프링 입문 강의(https://inf.run/hcic)를 수강하며 학습한 내용을 정리한 글입니다.

 

3. 회원 리포지토리 테스트 케이스 작성

 

<테스트 방법>

1. 자바의 main 메서드로 실행
2. 웹 애플리케이션의 컨트롤러를 통해 해당 기능 실행
→ 단점: 준비하고 실행하는 데 오래 걸리고, 반복 실행하기 어려우며 여러 테스트를 한번에 실행하기 어렵다

자바는 JUnit이라는 프레임워크로 테스트를 실행해서 이러한 문제를 해결한다.

 

1) src/test/java - repository 패키지 - MemoryMemberRepositoryTest클래스 생성

2) repository 이름으로 MemoryMemberRepository 객체 생성

 

3) 테스트 할 메서드 앞에 @Test 어노테이션을 붙여 준다
    각 메서드별 테스트 메서드를 작성하고 실행한 다음 결과가 올바르면 다음 테스트 메서드를 작성한다

    ˙save 메서드 테스트
       : 테스트에서 생성한 member를 save 한 후, DB에서 member의 Id로 찾은 값이 같은가?
         = 저장이 잘 되었는가?

22번 라인의 녹색 버튼으로 실행

 

AssertJ

자바 테스트를 위해 좀 더 풍부한 문법을 제공하고 메서드 체이닝을 통해 직관적인 테스트 흐름을 작성할 수 있도록 개발된 오픈 소스 라이브러리로, 많은 assertion을 제공한다

junit에서 제공하는 assertEquals의 인자 순서는 헷갈릴 가능성이 크며 가독성이 떨어진다
assertThat()은 actual 인자 하나만 요구하여 그 뒤로 메서드 체이닝을 통해 actural과 expected를 명확히 구분한다
assertEquals(expected, actual); //junit

assertThat(actual).isEqualTo(expected); //AssertJ

 

    ˙findByName 메서드 테스트

 

    ˙findAll 메서드 테스트

 

    ˙전체 테스트
       클래스 앞에 있는 Run 버튼으로 전체 테스트 메서드를 한 번에 테스트 할 수 있다

package hello.hellospring.repository;

import hello.hellospring.domain.Member;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;

import java.util.List;

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

class MemoryMemberRepositoryTest { //public 삭제(다른 곳에서 사용할 것 아니므로)

    MemoryMemberRepository repository = new MemoryMemberRepository();

    @Test
    public void save() {
        Member member = new Member();
        member.setName("spring");

        repository.save(member);

        Member result = repository.findById(member.getId()).get(); //Optional에서 값 꺼낼 때 get() 사용
        //new로 만든 member와 DB에서 꺼낸 값과 같으면 참이다
        //assertj가 제공하는 Assertions을 사용(더 편리하다), Alt + Enter로 import 해 준다
        assertThat(member).isEqualTo(result);
    }

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

        //정교한 테스트를 위해 member2 생성
        Member member2 = new Member(); //Shift + F6 rename 한 번에 해 준다
        member2.setName("spring2");
        repository.save(member2);

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

        assertThat(result).isEqualTo(member1);
    }

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

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

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

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


🚨 에러 발생: 테스트가 위에서부터 순서대로 이루어지지 않는다.
                    다른 테스트 메서드에서 저장한 객체가 다른 테스트 메서드에 영향을 준다
                    테스트는 각각 독립적으로 실행되어야 한다
                    테스트 순서에 의존관계가 있는 것은 좋은 테스트가 아니다

💡 해결 방법: 테스트는 서로 순서와 의존 관계가 없이 이루어져야 한다.
                   한 메서드의 테스트가 끝나면 클리어를 해 준다.
                   위의 소스 코드에서 한 테스트가 끝나면 repository가 비워지도록 한다.

 

MemoryMemberRepository.java에 코드 추가

public void clearStore() {
        store.clear();
    }

 

MemoryMemberRepositoryTest.java에 코드 추가

    @AfterEach
    public void afterEach() { //한 메서드 실행이 끝나면 동작되는 콜백 메서드
        repository.clearStore();
    }

 

@AfterEach

한번에 여러 테스트를 실행하면 메모리 DB에 직전 테스트의 결과가 남을 수 있다.
이렇게 되면 다음 이전 테스트 때문에 다음 테스트가 실패할 가능성이 있다.
@AfterEach를 사용하면 각 테스트가 종료될 때 마다 이 기능을 실행한다.
여기서는 메모리 DB에 저장된 데이터를 삭제한다.

 

전체 테스트 완료

 

댓글