스프링 입문 - 회원관리 예제와 테스트 케이스

hyuk·2023년 10월 4일
0
post-thumbnail

📌 회원관리 예제 - 백엔드 개발

  1. 비즈니스 요구사항 정리
  2. 웹 애플리케이션 계층 구조 설계
  3. 테스트 케이스

이번 회원관리 예제는 일반적인 웹 애플리케이션 계층 구조 맞추어 설계하며 학습하였다.
테스트 케이스의 경우, JUnit 테스트 프레임을 사용한다.


비즈니스 요구사항 정리

일반적인 웹 애플리케이션 계층 구조로, 컨트롤러, 서비스, 리포지토리, 도메인 객체, 데이터베이스와 같이 구성된다.

컨트롤러 : 웹 MVC의 컨트롤러 역할
서비스 : 비즈니스 도메인 객체가 핵심 비즈니스 로직이 동작하도록 구현
리포지토리 : 데이트베이스에 접근하며, 도메인 객체를 DB에 저장하고 관리
도메인 : 주로 데이터베이스에 저장하고 관리되는 비즈니스 도메인 객체

아직 데이터베이스가 선정되지 않았기에 메모리 기반의 저장소로 설계하며 학습을 진행했다.


Domain

    private Long id;
    private String name;


    public Long getId() return id; 

    public void setId(Long id) this.id = id; 

    public String getName() return name;
  
    public void setName(String name) this.name = name;
   

여기서 ID는 고객이 정하는 ID가 아닌 데이터를 구분하기 위한 ID이다.


Controller

 private static Map<Long, Member> store = new HashMap<>();
 private static long sequence = 0L;

동시성 문제로 HashMap이 아닌 ConcurrentHashMap 권장하며, sequence의 데이터 타입을 long이 아닌 Atomic long 권장한다.

공유되는 변수일 경우, 동시성 문제를 고려해야 한다.


Service

 private void validateDuplicateMember(Member member) {
 	memberRepository.findByName(member.getName())
 		.ifPresent(m -> {
 		throw new IllegalStateException("이미 존재하는 회원입니다.");
 	});
 }

위 코드는 중복 회원을 검증하는 로직을 구현한 코드로, .ifPresent() 메서드를 통해 검증한다.

.ifPresent() 메서드 경우, 값 존재할 경우, 예외를 발생

Repository

 @Override
 public Optional<Member> findById(Long id) {
 	return Optional.ofNullable(store.get(id));
 }

Optional<T>의 경우, NullPointerException을 피하기 위해 null 대신의 초기값으로 사용

Generic Class인 Optional<T>는 모든 참조변수를 담을 수 있는 Wrapper 클래스


📌 테스트 케이스

JUnit 프레임워크를 통해 오래 걸리고, 여러 테스트를 한 번에 실행시키기 어렵다는 점들을 해결 !

 @Test
 public void 중복_회원_예외() throws Exception {
 	//Given
 	Member member1 = new Member();
 	member1.setName("spring");
    
 	Member member2 = new Member();
 	member2.setName("spring"); 
    
    //When
 	memberService.join(member1);
    
    //Then
 	IllegalStateException e = assertThrows(IllegalStateException.class,
 			() -> memberService.join(member2));//예외가 발생해야 한다.
 	assertThat(e.getMessage()).isEqualTo("이미 존재하는 회원입니다.");
 }

초기 테스트 코드 작성 시에 Given ~ When ~ Then 같은 순서로 테스트를 진행하는 것이 권장한다.

테스트를 할 때에는 독립적으로 실행되야 하며, 순서에 의존관계가 있는 것은 좋은 테스트 ❌

AssertJJUnit 프레임워크에서 제공해주는 라이브러리

JUnit Annotation

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

@BeforeEach 애노테이션이 붙은 메소드의 경우, 테스트 메서드 실행 이전에 수행된다.

@AfterEach 애노테이션이 붙은 메소드의 경우, 테스트 메서드 실행 이후에 수행된다.


📌 본 포스트는 스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술 통해 학습한 내용을 요약 및 정리한 것입니다.

profile
차곡차곡쌓아가는학습노트

0개의 댓글