Spring/Spring boot 입문

[스프링 부트] 회원 관리 예제(4)~(5) - 스프링 입문 강의 / 인프런

mopipi 2022. 8. 3. 17:45
반응형

4. 회원 관리 예제 - 백엔드 개발


4) 회원 서비스 개발


회원 서비스 클래스 생성

  • 회원 서비스: 회원 리포지토리 + 도메인 활용해 비즈니스 로직을 작성하는 부분
  • (Repository에 비해) 서비스 클래스는 비즈니스에 가깝게 네이밍 해야 함 (∵ 비즈니스 처리하므로)
  • Service 패키지 생성 > MemberService 클래스 생성해 작업

1. MemberRepository 객체 생성 

- final : 여러 context에서 단 한번만 할당 될 수 있는 entity를 정의할 때 사용

  ➔ 객체 변수 final : 해당 변수에 다른 참조 값 지정 불가능 (재변경 불가능, 다른 객체로 변경 불가능) 

       (✔ 객체의 속성(=필드)는 변경 가능)

 

2. 메서드 정의 - (1)회원 가입 메서드 (join) 정의 

 

- 회원 가입 후 해당 id 반환 (Long) 설정

- 비즈니스 로직 中 같은 이름은 가입이 불가능하다고 설정

- Optional 이기에 ifPresent 가능 (∵ Optional 메서드임)  [Optional 안에 맴버객체가 있음]

  ⇋ Optional이 아니였다면 ifNull() 사용 

✔ Null일 가능성이 있는 변수, 객체를 다룰 때는 Optional로 한번 감싸서 사용하자! 
   (if) Optional에서 맴버 객체를 꺼내 쓰고 싶다?  ➤ get메서드 ( ex. result.get() ) [권장X]
        ✓ 값이 있을 때만 꺼내기 : orElseGet() [권장O]

➔ 별도의 변수 추가 없이 바로 판별해주는 것이 더 깔끔하다. (결과가 Optinal<Member>로 나오는걸 아는 경우)

+

특정 기능을 메서드로 뽑을 수 있는 단축키 (extract Method) : Ctrl + Shift + Alt + T → "7. Extract Method" 선택

중복 회원 검사 기능을 별도의 메서드로 추출해준다.

 

∴ 회원가입(join) 로직 = (1) 중복 회원 검증 (2) 통과하면 DB에 저장

 

2. 메서드 정의 - (2) 전체 회원 조회 (findMembers) 메서드, (3) id로 회원 찾기 (findOne) 메서드

3. 검증 하기 - 테스트 케이스 활용 ver.

 

  ➔ (5) 회원 서비스 테스트에서 계속...

 


5) 회원 서비스 테스트


3. 검증 하기 - 테스트 케이스 활용 ver. 

 ✔ 그 전엔 test 하위에 패키지 만들고 직접 작성해줘야 했음
    ➤ 간단하게 단축키를 이용하자! : 테스트할 클래스에 → Shift + Ctrl + T → Create New Test
    ➤ 테스트 라이브러리 (JUnit 5), 클래스 네임 자동으로 설정된 테스트 클래스 생성 
    ➤ 테스트할 메서드 선택
    ➤  test > service 패키지 자동생성> 하위에 MemberServiceTest 생성됨
java 하위에 생성한 패키지명과 동일하게 생성된다

♘ 테스트용 코드 작성법 : (1) given (2) when (3) then

  • given : 검증할 때 사용할 데이터 (비교 당할 데이터)
  • when : 검증할 사항 (제대로 작동하는지를 검증할 메서드는 어떤 것?)
  • then : 검증 부분 (어떤 방식으로 검증할 것인지?)

 

3. 검증 하기 - (1) 회원 가입 (join) 메서드

테스트용 메서드명은 한글로 바꿔도 됨! (직관적)

 

-  memberService로부터 찾은 회원을 Optional에서 바로 get으로 꺼내 Member 변수에 저장 (by (ctrl + alt + v))

- static import (alt + enter    Add on -~) 해서 Assertions 생략

무사히 통과

✔ 테스트에서는 예외 테스트도 매우 중요하다!!!
    ➤ join의 핵심은 중복 회원 검증 로직이 잘 작동하는지, 예외 (throw new IllegalStateException) 검증 필수
    ➤ "중복_회원_예외 메서드"를 추가로 생성해 중복 회원을 저장해보자!

- 같은 name을 가진 member 객체를 각각 member1, member2로 선언한 다음 join을 이용해 Memberservice에 저장

  [의도적으로 validateDuplicateMember가 작동해 Exception throw 되게끔 설정]

 

# 방법 1) try - catch 문으로 검사

...
memberService.join(member1);
try{
	memberService.join(member2); 
    fail("예외 발생 실패"); //Exception이 제대로 발생 안될경우 실행될 코드
}catch (IllegalStateException e){ //성공할 경우 catch 동작
	assertThat(e.getMessage()).isEqualTo("이미 존재하는 회원입니다.");
}

# 방법 2) assertThrows 이용

예외 검증 성공!

assertThrows("발생할 예외".class, () -> "문제가 될 부분")

메시지가 일치하는지로도 테스트 가능

얘도 마찬가지로 테스트마다 repository 초기화가 필요하다.
➔ member repository 가져와서 초기화 (after Each 동일하게 생성) 
✔ 이전 실행 명령어 다시 실행 = Shift + F10

BUT!!!

memberRepository 객체 (in MemberService 클래스) =/= memberRepository (in MemberServiceTest 클래스)

⇒ 각 객체를 다르게  구분지어 2개로 사용할 필요가 없고, 혹시 모르니 지양하는 것이 낫다.

 

 ✘ 문제 상황
    MemberService클래스와 해당 테스트 클래스에서 생성되는 MemoryMemberRepository 객체(instance)가 서로 다르다. (⇌ 서로 다른 repository이다) = 테스트해야 하는 것과 다른 repository 테스트
   (+!store가 static으로 설정되지 않는다면 문제 발생함 (다른 DB가 되는 것이므로))
 ✔ 해결 방법

Test에서도 같은 repository를 사용하게 한다. 
⇒ MemberService에서 Constructor를 선언 해준다. 
             (memberRepository를 직접 new로 생성하는 것이 아니라, 외부에서 인자로 넣어주도록 설계한다)
⇒ 테스트 수행 전에 memoryMemberRepository를 생성한 후 MemberService에 인자로 제공하면, 같은 MemoryMemberRepository로 사용됨

MemberService Class 입장에선 Repository를 직접 new하는 것이 아닌, 외부에서 생성된 memoryMember
Repository를 넣어서 생성  ➤➤➤ Dependency injection (DI: 의존성 주입)
✔ Generate (Constructor 생성) 명령어 = Alt + Insert
✔ 의존성 주입 = 내부에서 만든 변수를 외부에서 넣어주는 것 (의존관계를 외부에서 결정하고 주입)

DI [Dependency Injection] 

  • DI 종류
    • 필드 주입
    • setter 주입
    • 생성자 주입 (권장) : 의존 관계가 실행중에 동적으로 변하는 경우 거의 없음
반응형