회원 관리 예제2

구름코딩·2020년 10월 16일
0

회원 서비스 클래스 개발

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

개요

회원 서비스 Class

고객 객체인 memberRepository (인터페이스)을 이용해서 서비스 기능을 구현

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) {
        memberRepository.findByName(member.getName())
            .ifPresent(m -> {
                throw new IllegalStateException("이미 존재하는 회원입니다");
            });
    }

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

    public Optional<Member> findOne(Long memberId){
        return memberRepository.findById(memberId);
    }
}

회원 서비스 클래스 테스트

  • 테스트를 진행할 클래스의 클래스명에서 (지금은 MemberService) cmd-shift-t를 입력하면 자동으로 각 메소드에 대한 Test 기본 틀을 만들어 준다

  • @Test를 짤때 given, when, then으로 구분지어서 짜는것이 좋다

  • @Test메소드는 한글명으로 하는 경우도 흔하다, 매우 직관적이므로

MemberServiceTest Class

BeforeEach, AfterEach - 각 테스트 시작 전, 후 실행

    MemberService memberService;
    MemoryMemberRepository memberRepository;

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

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

회원가입 Test

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

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

    //then
    Member findMember = memberService.findOne(saveId).get();
    assertThat(member.getName()).isEqualTo(findMember.getName());
}

중복회원 예외 체크 Test

  • try-cathc 구문을 사용하는 방법
  • Assertions.assertThrows를 사용하는 방법 <- 주로 사용
@Test
public void 중복_회원_예외() {
    //given
    Member member1 = new Member();
    member1.setName("woonsik1");

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

    //when
    memberService.join(member1);

    //then
    /*
    try-catch 사용한 경우
    try {
        memberService.join(member2);
    } catch (IllegalStateException e){
        assertThat(e.getMessage()).isEqualTo("이미 존재하는 회원입니다");
    }
     */

    //assertThrows를 사용한 경우 -> 내가 원하는 예외클래스가 터지는지 학인한다
    assertThrows(IllegalStateException.class, () -> memberService.join(member2));
    
    //반환값으로 받아서 추가적인 확인도 가능하다
    IllegalStateException e = 
    	assertThrows(IllegalStateException.class, () -> memberService.join(member2));
    assertThat(e.getMessage()).isEqualTo("이미 존재하는 회원입니다");
}

DI - Dependecny-Injection 의존성 주입

  • IoC(역제어)의 한 부분이다
  • 해당 클래스에서 사용할 인스턴스 객체를 생성하는 것이 아니라 외부 클래스에서 생성한 객체를 받아와서 사용하는 방식
public class MemberService {

    private final MemberRepository memberRepository;

    //Dependency Injection == DI
    //현 클래스에서 생성하는 것이 아닌 외부에서 생성한 것을 넣어주는 형태
    public MemberService(MemberRepository memberRepository) {
        this.memberRepository = memberRepository;
    }
    
    //~내용~
    
}

의존성 주입 예제

MyClass가 AnotherClass에 의존관계에 있는 상황이다
만약 AnotherClass가 변경된다면 (인자가 String-> Integer 등) MyClass의 변경 또한 필요하다는 것이 명확하다

public class MyClass1{
    private AnotherClass anotherClass;

    public MyClass1(){
        this.anotherClass = new AnotherClass("언아더클래스");
        anotherClass.printName();
    }
}

이러한 의존 관계를 피하기 위해서 anotherClass를 더이상 MyClass에서 configure하지 않고
생성자의 인자로 받아버리는 것이다
이를 '의존성이 주입되었다' 또는 '제어가 역전되었다'라고 표현한다
실제로 "언아더클래스"라는 인자로 configured된 anotherClass를 받아야 한다는 사실을
더이상 MyClass는 알필요가 없게 되었다. 즉, 의존관계가 없어졌다
이를 통해 코드의 재사용성, Test 용이성을 얻을 수 있다

public class MyClass {
    private AnotherClass anotherClass;

    public MyClass(AnotherClass anotherClass){
        this.anotherClass = anotherClass;
        this.anotherClass.printName();
    }
}
profile
내꿈은 숲속의잠자는공주

0개의 댓글