(인프런) 김영한님의 스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술을 공부하고 리뷰한 글입니다.
1. 회원 서비스 테스트
테스트를 만드는 방법은 2가지가 있다. 방법1은 저번 회원 리포지토리 테스트 개발을 할 때 사용했던 방법이고 방법2는 단축키를 활용하여 테스트를 쉽게 만들 수 있는 방법이다. 2번 방법을 쓰는 것을 추천한다.
(방법1)
1) domain 패키지 생성
2) domain 패키지에 Member 클래스 생성
(방법2)
1) 테스트를 할 클래스(MemberService)에서 Ctrl+Shift+T 로 자동으로 테스트를 만든다.
(1, 2 과정이 자동으로 실행됨)
회원 객체(Member) 코드 작성
package hello.hellospring.service;
import hello.hellospring.domain.Member;
import hello.hellospring.repository.MemoryMemberRepository;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import static org.assertj.core.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.*;
class MemberServiceTest {
MemberService memberService; // 회원 서비스
MemoryMemberRepository memberRepository; // 메모리 회원 리퍼지토리
// 테스트가 독립적으로 실행되기 위해 서비스, 리퍼지토리 각각 생성되도록함
@BeforeEach
public void beforeEach() {
// 같은 메모리 레퍼지토리가 사용됨
memberRepository = new MemoryMemberRepository();
// 위에서 생성한 MemoryMemberReposiotory를 MemberService의 MemberRepository에 넣어줌
memberService = new MemberService(memberRepository);
}
// 테스트가 끝날 때마다 메모리 비우기
@AfterEach
public void afterEach() {
memberRepository.clearStore();
}
@Test
public void 회원가입() throws Exception {
// given
Member member = new Member();
member.setName("hello");
// when
Long saveId = memberService.join(member);
// then
// 우리가 저장한 것이 repository에 저장되었는지 검사
Member findMember = memberRepository.findById(saveId).get();
assertEquals(member.getName(), findMember.getName());
/*
*/
}
@Test
public void 중복_회원_예외() throws Exception {
// Given
Member member1 = new Member();
member1.setName("spring");
Member member2 = new Member();
member2.setName("spring");
// when
memberService.join(member1); // member1 회원가입
IllegalStateException e = assertThrows(IllegalStateException.class,
() -> memberService.join(member2)); // member2 회원가입 시 예외 발생
// 위에서 발생한 예외가 중복 회원 가입 예외인지 검증
assertThat(e.getMessage()).isEqualTo("이미 존재하는 회원입니다.");
/*
// when을 try-cath로 구현
try {
memberService.join(member2);
fail();
} catch (IllegalStateException e) {
// 예외가 터졌을 때 중복 회원 가입 예외인지 검증
assertThat(e.getMessage()).isEqualTo("이미 존재하는 회원입니다.");
}
*/
}
}
테스트 메서드 명은 한글로 적어도 상관없다!
<테스트 작성방법>
기본적으로 이 단계를 만족하도록 테스트를 작성할 수 있다. 간혹 그렇지 않은 경우도 있지만 초심자라면 더더욱 이것을 따르는 것이 좋다!!
1. given: 어떤 상황이 주어졌을 때(이 데이터 기반으로 함)
2. when: ~를 실행했을 때(검증할 것을 실행)
3. then: 검증한 결과가 ~가 나와야함
2. 기존 회원 서비스 코드를 DI 가능하게 변경
package hello.hellospring.service;
import hello.hellospring.domain.Member;
import hello.hellospring.repository.MemberRepository;
import hello.hellospring.repository.MemoryMemberRepository;
import java.util.List;
import java.util.Optional;
public class MemberService {
// 메모리 회원 리퍼지토리 직접 생성
//private final MemberRepository memberRepository = new MemoryMemberRepository();
private final MemberRepository memberRepository;
public MemberService(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
...
}
저번 글의 기존 회원 서비스 에서는 회원 서비스가 메모리 회원 리포지토리를 직접 생성했다.
하지만 이렇게 되면 문제가 발생한다. 왜 문제가 생기는지는 아래에서 설명하겠다.
일단 MemberServiceTest의 @AfterEach 로 각 테스트가 끝날 때마다 메모리 회원 리포지토리를 비워줘야한다. MemberServiceTest 클래스 내에서 MemoryMemberRepository를 생성해야 clearStore()를 호출해 메모리를 비워줄 수 있다. 그런데 MemberServiceTest에서 MemberService와 MemoryMemberRepository를 직접 생성하게 되면 문제가 발생한다.. store가 static이 아니면 MemberService에서 직접 생성한 MemoryMemberRepository와 MemberServiceTest에서 직접 생성한 MemoryMemberRepository는 다른 객체다!!
해결방법은 MemberService에서 MemberRepository를 작접 생성하는 것이 아니라,
위부(파라미터)로 받아온 MemberRepository를 넣어주는 방식으로 바꾸는 것이다!
인프런에서 유사한 질문, 답변을 참고하였습니다.
Q. MemberService 객체를 생성한 A 객체와
A. MemoryMemberRepository 객체가 2개(이하 A, B) 생성되었고 MemoryMemberRepository 내 store 변수에 static 키워드가 없다는 것을 전제로 설명드리겠습니다.
A에 Member(id:1, name:foo) 엔티티를 저장
B에 Member(id:100, name:bar) 엔티티를 저장
위와 같은 상황이라면 저장공간이 별도로 분리되어 있기 때문에 name을 foo로 가지는 데이터를 불러오려면 무조건 A에 접근해야 하는 상황이 발생합니다.
만약 static 키워드로 생성된 store 변수였다면 A, B객체는 store 변수를 공유하기 때문에 A, B 어디서든지 name을 foo로 가지는 데이터를 불러올 수 있습니다.
'Spring > 스프링 입문' 카테고리의 다른 글
[스프링 입문] 04. 스프링 빈과 의존 관계 - 자바 코드로 직접 스프링 빈 등록하기 (0) | 2022.04.28 |
---|---|
[스프링 입문] 04. 스프링 빈과 의존 관계 - 컴포넌트 스캔과 자동 의존 관계 설정 (0) | 2022.04.28 |
[스프링 입문] 03. 회원관리 예제(백엔드 개발) - 회원 서비스 개발 (0) | 2022.04.27 |
[스프링 입문] 03. 회원관리 예제(백엔드 개발) - 회원 리포지토리 테스트 케이스 작성 (0) | 2022.04.27 |
[스프링 입문] 03. 회원관리 예제(백엔드 개발) - 회원 도메인과 리포지토리 만들기 (0) | 2022.04.27 |