본문 바로가기
Framekwork/SPRING

[SPRING] 스프링 부트 - 회원 관리 예제 > 회원 서비스 개발 & 테스트

by 아이엠제니 2023. 9. 2.

 

 


 

1. 회원 서비스 개발

회원 서비스는 회원 리포지토리와 도메인을 활용해서 실제 비즈니스 로직을 작성함

 

💾 service/MemberService.java

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

    /**
     * 회원 가입
     */
    public Long join(Member member) {

        validateDuplicateMember(member); // 중복 회원 검증 , 기존 코드를 메소드로 만듦

        memberRepository.save(member);
        return member.getId();
    }

    private void validateDuplicateMember(Member member) {
        // 예전에는 if로 사용했는데, 요즘은 Optional로 감싸서 사용을 많이 함
        memberRepository.findByName(member.getName())
                .ifPresent(m -> {
                    throw new IllegalStateException("이미 존재하는 회원입니다.");
                });
    }

    /**
     * 전체 회원 조회
     */
    public List<Member> findMembers() {
        return memberRepository.findAll();
    }

    public Optional<Member> findOne(Long memberId) {
        return memberRepository.findById(memberId);
    }
}
  • 서비스 클래스는 비즈니스에 가까운 용어를 사용해야 함
  • 리포지토리의 경우에는 조금 더 개발스럽게 용어를 선택해야 함
  • 💡 역할에 맞게 네이밍을 해야 함

 

메소드 생성 단축키
  • windows: ctrl + alt + m

 

 


2. 회원 서비스 테스트

test class 생성 단축키
  • 해당 클래스명에서 ctrl + shift + t

  • `Create New Test`가 뜨는 것을 볼 수 있음

 

  • 테스트 할 메소드는 선택할 수 있음
  • 테스트 할 메솓 선택하고 `OK` 버튼 클릭함

 

  • 위와 같이 자동으로 생성된 것을 볼 수 있음

 

💾 test/service/MemberServiceTest.java

package hello.hellospring.service;

import hello.hellospring.domain.Member;
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 java.util.List;

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();
        memberService = new MemberService(memberRepository); // DI
    }


    @AfterEach // 메소드가 실행이 끝날 때마다 어떤 동작을 하는 것임. 콜백 메소드
    public void afterEach() {
        memberRepository.clearStore();
    }

    @Test
    void 회원가입() {

        // given
        Member member = new Member();
        member.setName("spring");

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

        // then
        Member findMember = memberService.findOne(saveId).get();
        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);
        IllegalStateException e = assertThrows(IllegalStateException.class, () -> memberService.join(member2));
        assertThat(e.getMessage()).isEqualTo("이미 존재하는 회원입니다.");

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

        // then
    }

    @Test
    void findMembers() {
        // given
        Member member = new Member();
        member.setName("spring");

        memberService.join(member);
        
        // when
        List<Member> findMembers = memberService.findMembers();

        // then
        assertThat(findMembers.size()).isEqualTo(1);
    }
}
  • 테스트는 한글로 바꿔도 됨. 직관적으로 볼 수 있어서 더 편할 수도 있음. 실제 코드에는 영향 없음
  • 테스트는 정상 flow도 중요하지만, 예외 flow가 훨씬 중요함

 

마지막 `findMember()` 메소드는 인강 실습에는 없어서 앞에 테스트했던 거 참고해서 만들었다.

원래는 findMembers 리스트에 member가 포함되는지도 테스트를 했는데, 정확히 어떻게 포함이 되는지 이해가 되질 않아서 이건 조금 더 고민을 해봐야할 것 같다.

 

그리고 또 하나!

멤버 객체를 생성해서 setName으로 "spring"을 담는 것까지는 했는데!

바로 findMembers()로 전체 데이터를 조회하려니, 1도 조회가 안 되는 거다.

왜 그런가 봤더니, 가입을 안 시킨 것... (바보)

사소한 듯 보이지만, 나에게는 사소하지 않은 것들을 고민하며 해결을 하니...

그래도 조금은 이해가 된다.

앞으로도 이런 마음으로 하기... (하면 된다.)

 

 

 

인프런 김영한 - <스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술> 실습
300x250