개발/Spring

[Spring] 스프링 입문 - 회원 서비스 테스트

y_lime 2024. 11. 7. 21:00

기존에 만들어놨던 MemberService 클래스에서 단축키 command + shift + T 입력 후 create new test 선택

위와 같이 선택 한 후 완료를 하면 test 아래에 MemberServiceTest파일이 생성 된다.

 

테스는 메서드를 한글로 입력해도 상관 없다 !! for 직관성

 

회원가입 

회원 가입을 하려면 member 먼저 만들어야한다.

give when then 패턴

: 주석으로 give, when, then을 입력한 후, 코드를 짜면 훨씬 수월하게 짤 수 있다.

@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());
}

 

⟹ 당연히 테스트 성공 !!

BUT 테스트 코드를 작성할 때, 더 중요한 것은 바로..

 

예외 flow (중복 회원 예외)

1) try - catch 사용

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

    Member member2 = new Member();
    member2.setName("spring");

    // when
    memberService.join(member1);
    try {
        memberService.join(member2);
        fail();
    } catch (IllegalStateException e) {
        assertThat(e.getMessage()).isEqualTo("이미 존재하는 회원입니다.");
    }

    // then
}

 

2) assertThrow 사용 (1번 보다 더 좋은 코드)

memberService.join(member1);
//when
assertThrows(IllegalStateException.class, () -> memberService.join(member2));

이때, IllegalStateException이 아닌 다른 Exception을 사용하면 테스트 실패가 된다.

 

테스트 순서에 영향받지 않도록, 테스트 메서드가 끝나면 clear 해주기

MemoryMemberRepository memberRepository = new MemoryMemberRepository();

    @AfterEach
    public void afterEach() {
        memberRepository.clearStore();
    }

repository를 불러와서, clearStore 해주기!

 

MemberService의 Repository와 MemberServiceTest 의 Repository 통일 시켜주기 ! !

현재 각각의 클래스에서 MemoryMemberRepository의 객체를 만들어줬기 때문에 서로 다른 instance이다.

public class MemoryMemberRepository implements MemberRepository{
    private static Map<Long, Member> store = new HashMap<>();

만약 static이 아닌 경우를 대비해서 (다른 DB가 되기 때문) 같은 걸로 test를 하는 것이 옳다.

public class MemberService {
    private final MemberRepository memberRepository;
    public MemberService(MemberRepository memberRepository){
        this.memberRepository = memberRepository;
    }

 

class MemberServiceTest {
    MemberService memberService;
    MemoryMemberRepository memberRepository;
    
    @BeforeEach
    public void beforeEach(){
        memberRepository = new MemoryMemberRepository();
        memberService = new MemberService(memberRepository);
    }

BeforeEach로 인해, 테스트를 실행할 때 마다 각각 MemberService와 MemoryMemberRepository를  생성해준다.

그러면서 MemberService에 memberRepository를 넣어줘서 결론적으로 MemberService 클래스에서도 같은 memberRepository를 사용한다.

 

memberService 입장에서, memberRepository를 외부에서 넣어준다 → dependency injection(di)

 

 

 


@참고자료

[인프런] 김영한 - 스프링 입문 강의 (무료)