앞서 만든 도메인, 리포지토리에 이어 서비스를 생성해 보겠다.
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 방식을 이용해서 테스트를 생성해보자
이름이 같은 두 회원이 회원가입 하려고 하면 에러 메시지를 출력하는지 확인
@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.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);
}
이 값을 생성자로 리포지토리를 받아 넣어주게 되면 리포지토리를 나중에 받아오게 될 경우에 서비스로 이용가능할 것이다.