🌱 Spring/회원 관리 예제

[Spring] 회원 서비스 테스트(Dependency Injection)

Younngjun 2023. 7. 5. 09:29

이전에 MemoryMemberRepositoryTest class에서 단축키 [command + shift + T]를 누르면 새로운 테스트(New Test)를 추가할 수 있다.

먼저 회원 가입 서비스 테스트 코드를 given-when-then 방식으로 작성한다.

회원가입이라는 함수에 새로운 Member 객체를 선언하고 초기화한다. MemberService의 join 메서드는 repository에 객체를 넣고 그 id 값을 반환하기 때문에, then에서 repository에서 그 id를 가진 객체를 추출하고 Assertions.assertThat을 통해 비교한다.

public class MemberServiceTest {

    MemberService memberService = new MemberService();

    @Test
    void 회원가입() {
        // given
        Member member = new Member();
        member.setName("hello");

        // when
        Long saveId = memberService.join(member);

        // then
        // Optional<Member> one = memberService.findOne(saveId).get();
        Member findMember = memberService.findOne(saveId).get();
        Assertions.assertThat(member.getName()).isEqualTo(findMember.getName());
    }

    @Test
    void findMembers() {

    }

    @Test
    void findOne() {

    }
}

 

 

중복 회원 검증 테스트

 

회원가입에서 핵심은 중복 회원 검증부이다. 이를 위해 테스트 메서드 중복_회원_예외 메서드를 선언한다. Member 객체 두 개(member1, member2)를 선언한 후 동일한 name을 부여하고, member1 객체를 가입시킨 후 try-catch 문을 통해 member2의 회원가입을 시도한다.

회원가입에 성공했다면 에러가 발생한 것이기 때문에 fail()을 실행하고, 실패했다면 실패한 메시지가 이전에 MemberService에 선언한 validateDuplicateMember 메서드에서 반환하는 문자열인지 비교하는 것이다.

public class MemberServiceTest {

    MemberService memberService = new MemberService();

    @Test
    void 회원가입() {
        // given
        Member member = new Member();
        member.setName("hello");

        // when
        Long saveId = memberService.join(member);

        // then
        // Optional<Member> one = memberService.findOne(saveId).get();
        Member findMember = memberService.findOne(saveId).get();
        Assertions.assertThat(member.getName()).isEqualTo(findMember.getName());

    }

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

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

        // when
        memberService.join(member1);

        // 방법 1. try-catch 넣는건 애매하다
        try {
            memberService.join(member2);
            fail("예외가 발생해야 합니다.");
        } catch (IllegalStateException e) {
            Assertions.assertThat(e.getMessage()).isEqualTo("이미 존재하는 회원입니다.");
        }

        // then
    }

    @Test
    void findMembers() {

    }

    @Test
    void findOne() {

    }
}

 

try-catch 뿐만 아니라 assertThrows문을 사용할 수 있다. 

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

 

"아래 로직을 실행하는데, IllegalStateException 에러가 터져야 한다."라는 의미를 가진다.

() -> memberService.join(member2)

 

clear() 함수로 repo 초기화

 

앞선 MemoryMemberRepositoryTest에서처럼 Member 객체가 repo에 계속 쌓이기 때문에 메서드 실행이 마칠 때마다 clear를 시켜줘야 한다. 하지만 MemberServiceTest에는 MemberService 객체만 선언하였지 Repo 객체는 따로 선언하지 않았기 때문에 Repo 객체를 추가해주고 MemoryMemberRepositoryTest에서 선언한 afterEach 함수를 선언한다.

public class MemberServiceTest {

    MemberService memberService = new MemberService();
    MemoryMemberRepository memberRepository = new MemoryMemberRepository();

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

    @Test
    void 회원가입() {
        // given
        Member member = new Member();
        member.setName("hello");

        // when
        Long saveId = memberService.join(member);

        // then
        // Optional<Member> one = memberService.findOne(saveId).get();
        Member findMember = memberService.findOne(saveId).get();
        Assertions.assertThat(member.getName()).isEqualTo(findMember.getName());

    }
    
    ...
}

 

하지만 MemoryMemberRepository를 굳이 새로운 객체를 생성할 필요가 없다. 같은 MemoryMemberRepository 인스턴스를 사용하도록 설정한다.

MemberService 객체를 생성할 때 MemoryMemberRepository를 직접 넣어주면 되는데, 우선 MemberService를 직접 생성하는 것이 아니라 외부에서 넣어주는 것으로 수정한다. 이를 Dependency Injection이라 한다.

public class MemberService {
    private final MemberRepository memberRepository;

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

    MemberService memberService;
    MemoryMemberRepository memberRepository;

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

 

출처

 

https://www.inflearn.com/course/스프링-입문-스프링부트

 

[무료] 스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술 - 인프런 | 강의

스프링 입문자가 예제를 만들어가면서 스프링 웹 애플리케이션 개발 전반을 빠르게 학습할 수 있습니다., - 강의 소개 | 인프런

www.inflearn.com