[스프링 입문] 회원관리 예제

김우경·2021년 1월 4일
0

Spring Framework

목록 보기
3/12

김영한님의 스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술을 보면서 공부한 내용입니다.

일반적인 웹 애플리케이션 계층 구조

  • 컨트롤러 : MVC에서의 컨트롤러 역할
  • 서비스 : 비즈니스 도메인 객체를 이용해서 핵심 비즈니스 로직 구현 -> 비즈니스 의존적으로 설계
  • 도메인 : db에 주로 저장되고 관리되는 비즈니스 도메인 객체
  • 리포지토리 : db에 접근해서 도메인 객체를 db에 저장하고 관리

회원 도메인과 레포지토리

회원 클래스의 의존 관계

  • 아직 db가 선정되지 않았다고 가정된 비즈니스 요구사항
  • 회원의 저장 → 인터페이스
    : 메모리 구현체로 사용 → 구현 클래스를 변경할 수 있게
  • 초기 개발 단계에서는 구현체로 가벼운 메모리 기반 db 사용

레포지토리

: db에 접근해서 도메인 객체를 db에 저장하고 관리
-> 아직 db가 선정되지 않았으므로 메모리구현체 MemoryMemberRepository사용
-> 실제 저장/조회 로직의 구현은 여기에

  • 생성자가 딱 하나면 @Autowired 생략 가능

Optional<>

: 요즘은 널이 반환될때의 처리를 Optional로 감싸서함

Mashmap<>과 0L의 sequence

: 동시성 문제가 고려되어 있지 않음, 실무에서는 ConcurrentHashMap, AtomicLong 사용 고려

JUnit을 사용한 테스트 케이스 작성

JUnit 이용하기

: 자바용 유닛테스트 프레임워크
-> 구현한 기능에 대한 단위 테스트가 가능하다.
-> 클래스 레벨 단위로도 테스트가 가능하다.

  • 테스트 코드 작성 위치는

@Test

  • @Test를 붙혀준다
import org.junit.jupiter.api.Test;

@Test
....

테스트 결과에 대한 검증 방법

1. println()으로 찍어보기

System.out.println("result = "+ (result == member));

매번 일일이 눈으로 검증할 수 없으므로 사용 x

2. assertEquals(a, b)

org.junit.jupiter.api.Assertions

****
Assertions.assertEquals(result, member);

3. assertThat(a).isEqualTo(b)

import static org.assertj.core.api.Assertions.*;

assertThat(member).isEqualTo(result);

가장 많이 사용하는 방법

save()에 대한 전체 테스트 코드

@Test
    public void save() {
        Member member = new Member();
        member.setName("spring");

        repository.save(member);
        Member result = repository.findById(member.getId()).get();
        //System.out.println("result = "+ (result == member));
        //Assertions.assertEquals(result, member);
        //Assertions.assertThat(member).isEqualTo(result);
    }

테스트끼리의 독립성 보장하기

각 테스트마다의 실행 순서가 보장되지 않으므로 순서에 관계없이, 의존관계 없이 독립적으로 설계해야됨

→ 하나의 테스트가 끝날때마다 repository 깔끔하게 지워줘야됨

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

와 같이 매 테스트케이스 실행 후 repository clear해줘야함

TDD

검증할 수 있는 테스트 틀을 먼저 만들고, 구현 클래스를 만들어서 돌려보기
-> 오늘 한 방법의 반대 순서

회원 서비스 개발

: 핵심 비즈니스 로직의 구현
-> 레포지토리보다 더 비즈니스 의존적으로 설계해야함

테스트 문법

@Test
void 회원가입() {
	//given -> 검증 데이터

	//when -> 검증하려는 것

	//then -> 검증하는 부분

}

와 같이 세부분으로 나눠서 테스트하면 쉬움

예외적인 케이스에 대한 처리

정상플로우 뿐만 아니라 예외 플로우에 대한 처리가 더 중요함

→ 이 예제에서 중복 회원 검증 로직 테스트

방법 1 try-catch 사용

memberService.join(member1);
try {
	memberService.join(member2); //두번째 조인시에 예외가 발생해야
	fail(); //정상적으로 예외가 발생하지 않은 경우의 처리
} catch (IllegalStateException e) {
	//예외가 정상적으로 발생한 경우
	Assertions.assertThat(e.getMessage()).isEqualTo("이미 존재하는 회원입니다.");
}

방법 2 assertThrows() 사용

memberService.join(member1);
IllegalStateException e = assertThrows(IllegalStateException.class, () -> memberService.join(member2));
Assertions.assertThat(e.getMessage()).isEqualTo("이미 존재하는 회원입니다.");

MemberSevice에서 DI 가능하게 수정

Service와 ServiceTest에서 다른 두개의 repository를 사용한다.

MemberService.java

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

MemberServiceTest.java

class MemberServiceTest {

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

	...
}

MemberService와 MemberServieTest가 각자 다른 repository를 생성해서 사용할 때, 문제가 될 수 있음

→ 같은 인스턴스 사용 하도록 수정해줘야

MemberService.java

public class MemberService {
    private final MemberRepository memberRepository;

    //직접 new로 생성하는 것이 아닌 외부에서 넣어줄 수 있도록 -> dependency injection
    public MemberService(MemberRepository memberRepository) {
        this.memberRepository = memberRepository;
    }
	...
}

MemberServiceTest.java

class MemberServiceTest {

    MemberService memberService;
    MemoryMemberRepository memberRepository;

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

@BeforeEach는 각 테스트 실행 전에 호출되어 항상 새로운 객체를 생성하고, 의존관계도 새로 맺어줌
-> 테스트끼리의 독립성 보장

출처

김영한님의 스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술을 보면서 공부한 내용입니다.

profile
Hongik CE

2개의 댓글

comment-user-thumbnail
2021년 1월 6일

오..나도 오늘 들었는데 정리 잘해따..

1개의 답글