티스토리 뷰
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
'스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술' 카테고리의 다른 글
스프링 DB 접근 기술 (0) | 2023.03.29 |
---|---|
스프링 빈과 의존관계 (0) | 2023.03.28 |
스프링 웹 개발 기초 - MVC와 템플릿 엔진, API (0) | 2023.03.27 |
5장 스프링 MVC 설정 (0) | 2023.03.22 |
스프링 - 회원 리포지토리 테스트 케이스 작성 (0) | 2023.03.16 |
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- th:selected
- reactStart
- C
- 서버전송
- @RequestParam
- C언어
- react 시작 오류
- CheckBox
- ID
- 다중체크박스 처리
- 제약조건
- SCP
- React
- optional
- JPA
- mircrosoft visual studio
- @Builder
- @reqeustBody
- 씹어먹는 C 언어
- 셀프로젝트
- 다른데서 react
- 아이디
- selectbox
- reactApp
- 셀렉트박스
- 받아오기
- 체크박스
- App
- commit 에러
- findFirstBy
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
글 보관함