Spring/스프링 입문

[스프링 입문] 03. 회원관리 예제(백엔드 개발) - 회원 리포지토리 테스트 케이스 작성

HSY_mumu 2022. 4. 27. 20:30
728x90

(인프런) 김영한님의 스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술을 공부하고 리뷰한 글입니다.

개발한 기능을 실행해서 테스트 할 때 1)자바의 main 메서드를 통해서 실행하거나, 2)웹 애플리케이션의 컨트롤러를 통해서 해당 기능을 실행한다. 이러한 방법은 준비하고 실행하는데 오래 걸리고, 반복 실행하기 어렵고 여러 테스트를 한번에 실행하기 어렵다는 단점이 있다. 자바는 JUnit(프레임워크)로 테스트를 실행해서 이러한 문제를 해결한다. 내가 쓴 코드가 잘 돌아가는지 확인하는 코드를 작성해야한다.

1. 회원 리포지토리 메모리 구현체 테스트

1) src/test/java 하위에 repository 패키지 생성
2) repository 패키지에 MemoryMemberRepository 클래스 생성
3) 회원 리포지토리 메모리 구현체 코드 작성
메모리 리포지토리의 메서드들이 제대로 작동하는지 확인하기 위한 테스트 코드이다.

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();    // 메모리에 있는 모든 member들을 삭제함(테스트 순서에 의존관계를 없애기 위해)
    }

    // 메모리에 member가 저장이 제대로 되는지 검증하는 함수
    @Test
    public void save() {
        // given (name이 spring인 member가 있을 때)
        Member member = new Member();
        member.setName("spring");

        // when (member를 메모리에 저장)
        repository.save(member);

        // then (메모리에 member가 잘 저장되었는지 검증)
        Member result = repository.findById(member.getId()).get();  // optional안의 member 객체 반환
        // 메모리에서 가져온 member가 위에서 생성한 member와 같은지 검증
        assertThat(result).isEqualTo(member);
    }

    // 메모리에 member가 저장이 제대로 되는지 검증하는 함수
    @Test
    public void findByName() {
        // given (메모리에 name이 spring1, spring2인 member 2개가 저장되어 있을 떄)
        Member member1 = new Member();
        member1.setName("spring1");
        repository.save(member1);

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

        // when (메모리에서 name이 spring1인 member 조회)
        Member result = repository.findByName("spring1").get(); // optional 안의 member 객체 반환

        //then (메모리에서 name에 해당하는 member가 잘 조회되는지 검증)
        // 메모리에서 name이 spring1인 member가 member1이 맞는지 검증
        assertThat(result).isEqualTo(member1);
    }

    // 메모리의 모든 member들이 제대로 조회되는지 검증
    @Test
    public void findAll() {
        // given (메모리에 name이 spring1, spring2인 member 2개가 저장되어 있을 떄)
        Member member1 = new Member();
        member1.setName("spring1");
        repository.save(member1);

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

        // when (메모리에 있는 모든 member 조회)
        List<Member> result = repository.findAll(); // 메모리의 모든 member들을 list로 반환

        // then (메모리의 모든 member들이 제대로 조회되는지 검증)
        // 메모리에 있는 모든 member 수와 위에서 저장한 member 수가 같은지 검사
        assertThat(result.size()).isEqualTo(2); // result.size()가 2와 맞는지 검사
    }

}

Q. @AfterEach 테스트 끝날 때마다 메모리에 있는 데이터를 지워줘야 하는 이유는?
한번에 여러 테스트를 실행하면 메모리 DB에 직전 테스트의 결과가 남을 수 있다. 이렇게 되면 다음 이전 테스트 때문에 다음 테스트가 실패할 가능성이 있다. @AfterEach 에서 각 테스트가 종료될 때 마다 메모리 DB에 저장된 데이터를 삭제한다. 테스트는 각각 독립적으로 실행되어야 한다. 테스트 순서에 의존관계가 있는 것은 좋은 테스트가 아니다!!

Q. 메모리에 member가 잘 저장되었는지 확인할 때 get()을 이용하여 result에 값을 대입하는 이유는?
우리는 member가 잘 저장되어있느지 확인하기 위해서 메모리에서 가져온 member와 위에서 생성한 member가 같은지 확인해야 한다. 그런데 findById()의 반환형Optional<Member>다. 즉, 그냥 꺼내면 Optional 객체이기 때문에 그 안의member객체를 얻기 위해서 get()을 이용해야한다.

    @Test
    public void save() {
		...
        // then (메모리에 member가 잘 저장되었는지 검증)
        Member result = repository.findById(member.getId()).get();  // optional안의 member 객체 반환
        Member result = repository.findById(member.getId());	// member를 value로 갖는 Optional 객체 반환
        // 메모리에서 가져온 member가 위에서 생성한 member와 같은지 검증
        assertThat(result).isEqualTo(member);   
    }
  • assertThat(actual).isEqualTo(expected): 실제값(actual)이 예상된값(expected)와 같은지 검사

asserThat에 관하여 더 자세한 정보를 얻고싶다면 [JAVA] UnitTest에서 사용하는 AssertThat이란? 을 참고하세요.

[참고] https://pjh3749.tistory.com/241

[AssertJ] JUnit과 같이 쓰기 좋은 AssertJ 필수 부분 정리

AssertJ가 core document를 새로운 github.io로 이전했네요 :) . 본 글은 AssertJ 공식 문서를 핵심 챕터를 선정하여 번역하며 정리한 글 입니다. http://joel-costigliola.github.io/assertj/assertj-core.html A..

pjh3749.tistory.com







728x90