[Spring 입문] - 5. 서비스 로직, 테스트

heyhey·2023년 1월 17일
0

Spring

목록 보기
5/23

앞서 만든 도메인, 리포지토리에 이어 서비스를 생성해 보겠다.

java/hello.springgod/service/MemberService

package hello.springgood.service;

import hello.springgood.domain.Member;
import hello.springgood.repository.MemoryMemberRepository;

import java.util.List;
import java.util.Optional;

public class MemberService {
    private final MemoryMemberRepository memberRepository = new MemoryMemberRepository();
/**회원가입*/
    public Long join(Member member){
        // 같은 이름이 있는 중복 회원 X
        validateDuplicateMember(member);
        memberRepository.save(member);
        return member.getId();

    }

    private void validateDuplicateMember(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);
    }
}

리포지토리를 불러와서 작업을 해준다.

회원가입

중복확인을 먼저 시도하고 통과가 되면 리포지토리에 저장을 한다.
ctrl + T + Extract Method : 메서드 안에서 직접 작성을 하다가 이 로직을 독립적인 메서드로 분리시키고 싶을 때 사용.

서비스 테스트

MemberService 클래스에 대고 cmd + shift + T 를 눌러보자
앞에서 만든 테스트 케이스가 그대로 똑같이 생긴다.

option + Enter : static import
cmd + option + v : 자동 변수 생성

회원가입

@Test
void 회원가입() {
    // given
    Member member = new Member();
    member.setName("hello");
    // when
    Long saveId = memberService.join(member);
    // then
    Member findMember = memberService.findOne(saveId).get();
    assertThat(member.getName()).isEqualTo(findMember.getName());
}

given / when / then 방식을 이용해서 테스트를 생성해보자

  • given : 새로운 member가 대기하는 상태
  • when : 이 member가 회원가입을 하면
  • then : 가입하고 받은 id를 통해 회원 목록 중에 있는지 확인한다.

중복 회원 예외 처리

이름이 같은 두 회원이 회원가입 하려고 하면 에러 메시지를 출력하는지 확인

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

    Member member2 = new Member();
    member2.setName("member1");
    // when
    memberService.join((member1));
    IllegalStateException e = assertThrows(IllegalStateException.class, () -> memberService.join(member2));
    assertThat(e.getMessage()).isEqualTo("이미 존재하는 회원입니다");
}

IllegalStateException e = assertThrows(IllegalStateException.class, () -> memberService.join(member2));

  • assertThrows(a,b) 두번 째 인자인 b를 실행하여 첫번째 인자인 예외 타입과 같은지 검사한다.
  • 이 값 (e)에 대해 e.getMessage()를 하게 되면 에러 내용을 알 수 있다.
  • assertThrow를 사용하기 위해서는 다음과 같이 불러와야한다.
  • import static org.junit.jupiter.api.Assertions.assertThrows;

리포지토리

현재 여기서는 리포지토리를 불러올 때 다음과 같이 불러오고 있다.

MemberService memberRepository = new MemoryMemberRepository();
MemoryMemberRepository memberService = new MemberService();

하나는 서비스의 내용이고, 하나는 리포지토리이다.
new MemoryMemberRepository();를 통해 매번 새로운 인스턴스를 생성하고 있다.
이 테스트에서는 별다른 문제가 없을지 모르지만, 다른 곳에서도 사용되는 DB 같은 것을 사용한다면 문제가 생긴다.

그래서 다른 테스트에서도 공용의 인스턴스를 사용하기 위해서 서비스의 내용을 바꿔주도록 한다.

private final MemoryMemberRepository memberRepository = new MemoryMemberRepository();

MemberService의 기존의 리포지토리는 항상 새롭게 생성했었다.

private final MemoryMemberRepository memberRepository ;
public MemberService(MemoryMemberRepository memberRepository){
    this.memberRepository = memberRepository;
}
@BeforeEach
public void beforeEach(){
    memberRepository = new MemoryMemberRepository();
    memberService = new MemberService(memberRepository);
}

이 값을 생성자로 리포지토리를 받아 넣어주게 되면 리포지토리를 나중에 받아오게 될 경우에 서비스로 이용가능할 것이다.

profile
주경야독

0개의 댓글