본문 바로가기

Backend/spring

[ 스프링 ] 다양한 db연결방법 ( 3편 test code, JUnit, AssertJ )

728x90

[시작]

이전 다양한 db연결방법 ( 2편 Jdbc , JdbcTemplate , Jpa , Spring Data Jpa )에 이어서 이번에는 이전 시간에 만든 코드를 테스트 코드를 통해서 검증하는 방법을 알려드리려고 합니다.

 

들어가기 전에 아래 설명에서는 전체적인 흐름 이해를 위하여 간단하게 구조나 부분 코드만  보여주기 때문에 전체 코드를 보시고 싶으시면 아래 github링크를 확인해 주세요.


[Test code 작성 전 준비]

준비

우선 본 프로젝트에서는 테스트코드를 작성하기 위해 junit, assertJ 2가지 프레임워크를 사용할 예정입니다.

  • JUnit : 자바 단위테스트를 위한 프레임워크
  • AssertJ : 오픈소스 라이브러리로 에러 메시지와 테스트 코드의 가독성을 높여줌

이렇게 두가지를 활용하여 테스트 코드를 작성하면 매우 간단하고 가독성 높은 테스트 코드를 작성할 수 있습니다.

테스트 코드 구조

테스트 코드를 작성할 때 가장 많이 쓰이는 패턴으로 given-when-then 패턴이 있습니다.

  • given : 테스트할 값을 설정
  • when : given에서 설정한 값으로 진행할 테스트 설정
  • then : 테스트가 모두 끝났을 때 기대하는 결과와 같은지 확인

저도 이번에 알아보다가 알게된 패턴인데 이렇게 테스트를 진행하면 코드상 에러를 찾는데 많은 도움이 되는 것을 느꼈습니다. 앞으로 TDD로 하려고 노력해야겠네요.


[Service Test]

코드 보기 전에 설명이 길었네요. 😅

역시 글로 백번 보는 거보다 이제 직접 코드를 확인해 보도록 합시다.

글에서는 이전 시간에 작성한 최종 코드인 jpa를 테스트해볼 예정입니다. repository와 memory로 구현한 테스트 코드를 보시고 싶으시면 맨 밑에 제 githum에 코드를 올려드렸습니다.

테스트 코드 작성 전 준비

경로는 이미 눈치채신 분들도 있겠지만 최초 프로젝트를 시작하면 main폴더와 같은 레벨에 test라는 폴더를 발견하셨을 겁니다. main폴더와 마찬가지로 보기 편하도록 repository, service 나누어 테스트 파일을 만들었습니다.

본 예제에서는 UserInfoIntegrationTest를 설명하겠습니다.
테스트 코드 작성전 준비

  • 우선 스프링 부트 전체 테스트를 위해 SpringBootTest라는 어노테이션과 h2디비 테스트를 위해 Transactional어노테이션을 사용해 주겠습니다.
  • 테스트할 UserInfoService, UserInfoRepository를 위해 Autowired로 DI(Dependency Injection)을 해줍니다.
  • 이후 각 테스트 메서드 앞에 Test어노테이션을 붙여주면 됩니다.

(테스트 코드의 메서드 이름은 보기 쉽게 한국어로 작설 할 수 있습니다.)

회원가입

회원가입 확인

  • given : 이름 name과 이메일 email인 객체를 생성
  • when : given에 생성된 객체로 가입
  • then : 가입 시 저장한 user id를 findOne을 사용하여 검색 후 AssertJ의 assertThat을 통해서 검색한 id와 가입한 id가 같은지 판별

중복 회원 예외

중복 회원 예외 확인

  • given : 가입할 객체 생성
  • when
    1. given에서 생성한 객체로 가입
    2. JUnit의 assertThrows를 통해 동일한 객체로 다시 가입 후 IllegalStateException의 메시지를 e에 저장
  • then : 중복 가입시 나는 메시지가 "이미 존재하는 회원입니다." 인지 판별

유저 정보

모든 유저정보 확인

  • given : 서로 다른 UserInfo객체 생성 후 가입
  • when : 가입한 유저를 모두 조회
  • then : assertThat으로 가입한 유저의 수가 3명인지 확인 ( 이전 글에서 h2 database에 가입한 유저 1명 포함 )

유저 찾기

가입한 유저 찾기

  • given : 가입할 객체 생성 후 가입
  • when : 가입한 유저를 검색
  • then : 가입한 유저와 검색한 유저가 같은지 판별

[실행]

모든 테스트 실행

모든 테스트를 성성했습니다. 테스트하는 방법은 각각 메서드마다 실행해도 되고 저처럼 test폴더에 커서를 두고 control + sift + r을 누르면 전체 코드를 테스트합니다. 모두 초록색으로 체크 모양이 떴으면 잘 실행된 것입니다. 👍👍👍


[코드]

import com.tstory.yline.hellouser.domain.UserInfo;
import com.tstory.yline.hellouser.repository.UserInfoRepository;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

import static org.assertj.core.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.assertThrows;

@SpringBootTest
@Transactional
public class UserInfoIntegrationTest {

    @Autowired UserInfoService userInfoService;
    @Autowired UserInfoRepository userInfoRepository;

    @Test
    public void 회원가입(){
        // given
        UserInfo userInfo = new UserInfo("name", "email");

        // when
        Long saveId = userInfoService.join(userInfo);

        // then
        UserInfo result = userInfoService.findOne(saveId).get();
        assertThat(result.getEmail()).isEqualTo(userInfo.getEmail());
    }

    @Test
    public void 중복_회원_예외(){
        // given
        UserInfo userInfo = new UserInfo("rys", "rys@gmail.com");

        // when
        userInfoService.join(userInfo);
        IllegalStateException e = assertThrows(IllegalStateException.class, () -> userInfoService.join(userInfo));

        // then
        assertThat(e.getMessage()).isEqualTo("이미 존재하는 회원입니다.");
    }

    @Test
    public void findUserInfos(){
        // given
        UserInfo userInfo1 = new UserInfo("name1", "email1");
        userInfoService.join(userInfo1);
        UserInfo userInfo2 = new UserInfo("name2", "email2");
        userInfoService.join(userInfo2);

        // when
        List<UserInfo> result = userInfoService.findUserInfos();

        // then
        assertThat(result.size()).isEqualTo(3);
    }

    @Test
    public void findOne(){
        // given
        UserInfo userInfo = new UserInfo("yline", "email@gmail.com");
        userInfoService.join(userInfo);

        // when
        UserInfo result = userInfoService.findOne(userInfo.getId()).get();

        // then
        assertThat(result.getEmail()).isEqualTo(userInfo.getEmail());
    }
}

다음번에는 저희가 만든 프로젝트의 각각의 기능이 동작하는 시간을 알아보기 위해 AOP 설정하는 방법에 대해서 알려드리겠습니다. 지금까지 긴 글 읽어주셔서 감사합니다.🙇‍♂️


[출처]

 

[무료] 스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술 - 인프런 | 강의

스프링 입문자가 예제를 만들어가면서 스프링 웹 애플리케이션 개발 전반을 빠르게 학습할 수 있습니다., - 강의 소개 | 인프런...

www.inflearn.com


 

[ 스프링 ] 다양한 db연결방법 ( 2편 Jdbc , JdbcTemplate , Jpa , Spring Data Jpa )

[시작] 이전 다양한 db연결방법 (1편 HashMap)에 이어서 이번에는 Jdbc, JdbcTemplate, Jpa, Spring Data Jpa로 repository를 변경하는 적업을 알려드리려고 합니다. 이번 글에서 db를 정하고 변경하기 위하여 이..

yline.tistory.com

 

GitHub - yline0808/spring-db-conn

Contribute to yline0808/spring-db-conn development by creating an account on GitHub.

github.com

제가 잘못 알고 있거나 잘못된 부분이 있을 경우 알려주시고 추가로 궁금한 점 있으신 분들도 댓글이나 메일 주시면 성실히 답변해 드리겠습니다.🧑🏻‍💻

감사합니다~😄

728x90