티스토리 뷰

728x90

비즈니스 요구사항 정리

회원 도메인과 리포지토리 만들기

회원 리포지토리 테스트 케이스 작성

회원 서비스 개발

회원 서비스 테스트

비즈니스 요구사항 정리

  • 데이터 : 회원 ID, 이름
  • 기능 : 회원 등록, 조회
  • 아직 데이터 저장소가 선정되지 않음 ( 가상의 시나리오 )

  • 컨트롤러 : 웹 mvc의 컨트롤러 역할
  • 서비스 : 핵심 비즈니스 로직 구현
  • 리포지토리 : 데이터베이스에 접근, 도메인 객체를 DB에 저장하고 관리
  • 도메인 : 비즈니스 도메인 객체, 예)회원, 주문, 쿠폰 등등 주로 데이터베이스에 저장하고 관리됨

  • 아직 데이터 저장소가 선정되지 않아서, 우선 인터페이스로 구현 클래스를 변경할 수 있도록 설계
  • 데이터 저장소는 RDB,NoSQL 등등 다양한 저장소를 고민중인 상황으로 가정
  • 개발을 진행하기 위해서 초기 개발 단계에서는 구현체로 가벼운 메모리 기반의 데이터 저장소 사용

회원 도메인과 리포지토리 만들기

회원 객체
package hello.hellospring.domain;
public class Member {

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;
    }
}
Member repository interface
package hello.hellospring.repository;

import hello.hellospring.domain.Member;

import java.util.List;
import java.util.Optional;

public interface MemberRepository {
   Member save(Member member);
   Optional<Member> findById(Long id);
   Optional<Member> findByname(String name);
   List<Member> findAll();

}
Member MemoryMemberRepository
package hello.hellospring.repository;

import hello.hellospring.domain.Member;

import java.util.*;

public class MemoryMemberRepository implements MemberRepository{
   // 실무에서는 동시성 문제가 있을 수 있어서 공유되는 변수일 때는 컨커런트 해쉬맵을 쓴다
   private static Map<Long, Member> store = new HashMap<>();
   //시퀀스는 0 1 2 이런 키 값을 생성해준다
   private static long sequence = 0L;

   @Override
   public Member save(Member member) {
      member.setId(++sequence);
      store.put(member.getId(), member);
      return member;
   }

   @Override
   public Optional<Member> findById(Long id) {
      // 널이 반환 될 가능성이 있으면 Optional로 감싼다
      // 클라이언트에서 어떤 동작이 가능하게 하기 위해
      return Optional.ofNullable(store.get(id));
   }

   @Override
   public Optional<Member> findByname(String name) {
     return store.values().stream()
                  .filter(member -> member.getName().equals(name))
                  .findAny();
         // member.getName 이 파라미터로 넘어온 name 과 값이 같은지 확인
         // 같은 경우만 리턴이 된다
         // findAny()는 하나라도 찾는 것.
         // 끝까지 돌렸는데 없으면 Optional에 null이 포함 돼서 반환

   }

   @Override
   public List<Member> findAll() {
      // sotre.values 가 member 들이 반환 된다
      return new ArrayList<>(store.values());
   }
}
  • 검사할 때 확인 방법 : Test case 작성

MemberRepository Test case

  • 개발한 기능을 실행에서 테스트 할 때 자바의 main 메서드를 통해서 실행하거나, 웹 애플리케이션의
    컨트롤러를 통해서 해당 기능을 실행한다. 이러한 방법은 준비하고 실행하는데 오래 걸리고, 반복 실행하기
    어렵고 여러 테스트를 한번에 실행하기 어렵다는 단점이 있다
  • 자바는 JUnit이라는 프레임워크로 테스트를 실행해서 이러한 문제를 해결
  • test는 모두 따로 동작하게 작성 돼야 한다.
package hello.hellospring.repository;

import hello.hellospring.domain.Member;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;

import java.util.List;
import java.util.Optional;

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

public class MemoryMemberRepositoryTest {

   MemoryMemberRepository repo = new MemoryMemberRepository();

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

      repo.save(member);

      //Optional 에서 값을 꺼낼 때는 ... .get()
      Member result = repo.findById(member.getId()).get();
//      Assertions.assertEquals(member, null);
      // 조금 더 편하게 쓰게 해주는

      //member 가 result랑 똑같아?
      assertThat(member).isEqualTo(result);
   }

   @Test
   public void findByName(){
      Member member1 = new Member();
      member1.setName("summer1");
      repo.save(member1);

      Member member2 = new Member();
      member2.setName("summer2");
      repo.save(member2);

      Member result = repo.findByname("summer1").get();
      assertThat(result).isEqualTo(member1);

      List<Member> result1 = repo.findAll();

      assertThat(result1.size()).isEqualTo(3);


   }
}

Test는 의존성 없이 설계 되어야 한다. 한번 실행 후 모든 내용 지운 뒤 다른 Test 실행

  //Test 끝난 후 클리어 해주는 메서드
   // 콜백 메서드
   @AfterEach
   public void afterEach(){
      repo.clearStore();
   }

TTD - Test 주도 개발 ( Test 클래스를 먼저 작성하고, 실제 실행 클래스를 만드는 것 )

  • Test를 먼저 만들고 구현 클래스를 만드는 것
728x90
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/07   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
글 보관함