서비스 테스트 코드

DOYOUNG KIM·2023년 11월 11일
0

Spring프레임워크

목록 보기
3/18

💻 스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
실제 강의 링크

작성할 테스트 코드의 서비스 함수이다.
아래 서비스 함수는 회원 가입 및 회원 찾기 기능이다.

회원의 서비스의 기능은 비지니스 로직의 이름으로
회원 DB에 관련된 기능은 좀 더 개발스럽게 작명하는게 좋다.

아래 코드를 기반해서 테스트 코드를 작성해보자

public Long join(Member member){
        //중복 이름 회원 허용 X
        /**
         * 중복 회원을 허용 하지 않는 로직을 구현하느 것이 핵심이다.
         * 먼저 회원이 있나 찾아야함
         *
         * 영한님은 옵셔널 반환을 굳이 안한다
         */
        // Option 반환 인자 선언 후 실행 이 아닌 바로 isPresnet 적용
//        Optional<Member> result = memberRepository.findByName(member.getName());
//        result.ifPresent(m->{
//            throw new IllegalStateException("이미 존재하는 회원입니다.");
//        });

        validateDuplicate(member); // 중복 회원 검증

        memberRepository.save(member);
        return  member.getId();
    }

    private void validateDuplicate(Member member) {
        memberRepository.findByName(member.getName())
                        .ifPresent(m -> {
                            throw  new IllegalStateException("이미 존재하는 회원입니다.");
                        });
    }
    
    public List<Member> findMembers(){
        return memberRepository.findAll();
    }

    public Optional<Member> findOne(Long memberId){
        return memberRepository.findById(memberId);
    }

영한님이 테스트 코드를 작성할 떄 기본 구조로 제안한 것은
given / when /then 구조이다.

  • given : 시나리오 진행에 필요한 값 준비 / 테스트 준비
  • when : 시나리오 진행 조건 명시 / 테스트 행위
  • then : 시나리오 완료 보장 결과 / 테스트 결과

이 구조를 기반으로 테스트 케이스를 작성한다.
각 회원들을 가입이 정상 동작 하는지 또 중복 회원을 잘 걸러내는지 확인한다

여기서 테스트 케이스의 목적은 정상 동작 확인도 있지만
예외 상황을 잘 처리 하는지도 중요

test 회원이 가입했을떄 test라는 회원이 다시 가입을 하면 예외처리가 되어 이미 존재하는 회원이라는 에러 메시지를 반환한다.

class MemberServiceTest {
    MemberService memberService;
    MemoryMemberRepository memberRepository;
    //MemoryMemberRepository memberRepository = new MemoryMemberRepository();//이거를 두개를 쓸 이유가 없음 새로운 인스턴스로 할당하는게 좋지 않다.

    @BeforeEach
    public void beforeEach(){
        memberRepository = new MemoryMemberRepository();
        memberService = new MemberService(memberRepository);
    }
    @AfterEach
    public void afterEach(){
        memberRepository.clearStore();
    }
    @Test
    void 회원가입() {
        //given
        Member member = new Member();
        member.setName("test");
        //when
        Long saveId = memberService.join(member);
        //then
        Member findMember = memberService.findOne(saveId).get();
        Assertions.assertThat(member.getName()).isEqualTo(findMember.getName());
    }
    //예외 플로우가 매우 중요
    // 저장 보다 중복 회원도 중요

    @Test
    public void 중복회원체크(){
        //given
        Member member1 = new Member();
        member1.setName("test");

        Member member2 = new Member();
        member2.setName("test");
        //when
        memberService.join(member1);
        IllegalStateException e = assertThrows(IllegalStateException.class, () -> memberService.join(member2));
        Assertions.assertThat(e.getMessage()).isEqualTo("이미 존재하는 회원입니다.");
        //        try {
//            memberService.join(member2);
//            fail();
//        }catch (IllegalStateException e){
//            Assertions.assertThat(e.getMessage()).isEqualTo("이미 존재하는 회원입니다.");
//        }
        //then
    }
    @Test
    void findMembers() {
    }

    @Test
    void findOne() {
    }
}

현재 생성된 회원 리포지토리는 static으로 Map이 구성
만약 static이 아닌 경우에는 new로 새로운 리포지토리를 회원 정보에 새로 할당한다면 빌드 환경과 테스트 환경에서 서로 다른 리포지토리를 사용하는 것으로 추후 치명적인 문제로 이어질 수 있다.

그렇기 때문에 MemberService 객체에서 선언과 동시에 할당하는 것이 아닌 생성자를 이용해서 할당하는 방법으로 문제를 해결한다.

유닛 테스트, 통합 테스트와 같은 테스트는 웹 개발에서 중요한 요소이고 앞으로 우테코에서 지향하는 TDD에 대해서 더 깊게 알아보겠다.

profile
매일 1%씩 성장하는 개발 공부 블로그 입니다.

0개의 댓글

관련 채용 정보