출처) 인프런 스프링 입문 강의
회원 서비스 생성
이전에 생성한 도메인, 레포지토리로 비즈니스 로직을 작성
sr/cmain/java/hello.hellospring/service 패키지 생성
아래에 MemberService 클래스 생성
/** 회원 가입 **/
public Long join(Member member){
// 같은 이름이 있는 중복 회원 X
Optional<Member> result = memberRepository.findByName((member.getName()));
result.ifPresent(m -> {
throw new IllegalStateException("이미 존재하는 회원입니다.");
});
memberRepository.save(member);
return member.getId();
}
option + command + v 단축키: Optional ~ 자동 완성해줌
optional로 감싸면 메서드를 사용할 수 있음
ifPresent 메서드를 사용해서 값이 있으면 이미 존재하는 회원 (중복 가입 방지)임을 알림
더 깔끔하게 코드를 작성하는 방법
memberRepository.findByName((member.getName()))
.ifPresent(m -> {
throw new IllegalStateException("이미 존재하는 회원입니다.");
});
result 변수에 저장하지 않고 조회 결과 값으로 메서드 호출
control+t 단축키: 원하는 코드 드래그 후 method 검색하면 메서드가 생성됨
서비스 클래스는 비즈니스 쪽 네이밍을 해야함
반면, 레포지토리 클래스는 단순한 기능 위주의 네이밍을 함
이미 레포지토리에 findAll 메서드를 만들어 두었기 때문에 호출 값을 리턴해줌
/**
* 전체 회원 조회
*/
public List<Member> findMembers(){
return memberRepository.findAll();
}
memberId로 회원을 조회하는 메서드
이미 레포지토리에 findById가 있으므로 호출 값을 리턴해줌
/**
* 아이디로 회원 조회하기
*/
public Optional<Member> findOne(Long memberId){
return memberRepository.findById(memberId);
}
위에서 생성한 회원가입 기능에서, 중복 가입인 경우 exception이 터지는지 테스트 해보기
클래스에서 cmd + shift + t 누르면 테스트 생성할 수 있음

테스트 라이브러리 Junit5 선택, 원하는 멤버 체크

test 폴더에 같은 service 패키지 안에 테스트 app이 생성됨

이제 각 멤버에 대해서 테스트 할 코드를 작성
테스트 코드는 빌드에 포함되지 않기 때문에 더 직관적인 코드를 원한다면
메서드 이름을 한글로 바꿔도 괜찮음
테스트에 앞서서 MemberService 객체부터 생성
머리 가슴 배처럼 given, when, then으로 나눠 작성
어떤 걸 줬을 때 (given), 뭘 검증할 것인지 (when), 검증 결과 (then)
주석을 달아서 작성하는 것이 좋음
Assertions에 assertions 없으므로 static import 해줌
package hello.hellospring.service;
import hello.hellospring.domain.Member;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.*;
class MemberServiceTest {
MemberService memberService = new MemberService();
@Test
void 회원가입() {
// given
Member member = new Member();
member.setName("hello");
// when
Long saveId = memberService.join(member);
// then
Member findMmember = memberService.findOne(saveId).get();
assertThat(member.getName()).isEqualTo(findMmember.getName());
}
처음 회원 가입하는 테스트
join 으로 회원 가입하고 리턴 받은 회원 아이디를 saveId에 저장
이후 저장된 멤버를 꺼내서 findMember에 저장하고, 가입한 멤버와 저장된 멤버가 일치하는지
isEqualTo로 검증
이름이 같은 멤버를 생성하고 join할 때 두 번째 멤버의 join에서 IllegalStateException 발생
e로 저장하고 getMessage 해서 검증하면 됨
@Test
void 중복_회원_에외() {
//given
Member member1 = new Member();
member1.setName("spring");
Member member2 = new Member();
member2.setName("spring");
//when
memberService.join(member1);
IllegalStateException e = assertThrows(IllegalStateException.class, () -> memberService.join(member2));
assertThat(e.getMessage()).isEqualTo("이미 존재하는 회원입니다.");
}
계속 테스트하다보면 이미 spring 계정이 있기 때문에 member1을 생성할 때부터 오류가 발생함
clearStore 해주는게 필요, 현재 코드에서는 service만 생성했기 때문에, 레포지토리도 가져옴
MemoryMemberRepository memberRepository = new MemoryMemberRepository();
@AfterEach
public void afterEach(){
memberRepository.clearStore();
}
그러나 memberService, memberRepository를 각각 만들면 현재 코드에서는 store가 static이라 상관이 없지만 아닌 경우에는 다른 DB가 되기 때문에 코드를 수정하는게 필요함
➡️ 같은 인스턴스를 사용하게 수정
MemberService에서 레포지토리를 new로 생성하는게 아니라, 외부에서 받아서 생성하는 걸로 수정함
// 기존 코드
// private final MemberRepository memberRepository = new MemoryMemberRepository();
// 변경한 코드
private final MemberRepository memberRepository;
public MemberService(MemberRepository memberRepository){
this.memberRepository = memberRepository;
}
MemberServiceTest 에서도 memberService 객체를 생성할 때 레포지토리를 넘겨줌
beforeEach로 테스트 시행 전에 새 레포지토리를 생성하고, memberService 생성자인자로 넘기기
Dependency Injection (DI) 라고함
MemberService memberService;
MemberRepository memberRepository;
@BeforeEach
public void beforeEach(){
memberRepository = new MemoryMemberRepository();
memberService = new MemberService(memberRepository);
}
전체 코드
package hello.hellospring.service;
import hello.hellospring.domain.Member;
import hello.hellospring.repository.MemberRepository;
import hello.hellospring.repository.MemoryMemberRepository;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.*;
class MemberServiceTest {
MemberService memberService;
MemberRepository memberRepository;
@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("hello");
// when
Long saveId = memberService.join(member);
// then
Member findMmember = memberService.findOne(saveId).get();
assertThat(member.getName()).isEqualTo(findMmember.getName());
}
@Test
void 중복_회원_에외() {
//given
Member member1 = new Member();
member1.setName("spring");
Member member2 = new Member();
member2.setName("spring");
//when
memberService.join(member1);
IllegalStateException e = assertThrows(IllegalStateException.class, () -> memberService.join(member2));
assertThat(e.getMessage()).isEqualTo("이미 존재하는 회원입니다.");
}
@Test
void findOne() {
}
}