코딩하기 전 보통 웹 개발할 때 전체 느낌(?)
- 도메인 = 비지니스 도메인 객체 ex) 회원, 책, 가게
- 컨트롤러 = 사용자에게 들어온 요청을 처리하고 흐름을 제어
ex) 사용자 요청에 따라 적절한 Model 호출하고, Model에 데이터 적절하게 가공해서 보내주고, 비지니스 로직이 완료되면 결과 View에 전달하기 - 서비스 = 비지니스 로직을 처리
- 리포지토리 = DB 저장 및 관리
1. 회원 도메인 생성
[프로젝트 - src - main - java - com.그룹.이름]에 회원 객체를 나타내는 Member 클래스를 만든다.
//Member.java
public class Member {
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
2. 회원 리파지토리 생성
[프로젝트 - src - main - java - com.그룹.이름]에 회원 객체를 저장하는 MemberRepository 인터페이스와 MemoryMemberRepository 클래스를 만든다. Memory, DB 등에 따라 데이터 저장하는 코드가 다르니까 MemberRepository 인터페이스를 생성하고 그걸 Implements 해서 (종류마다의) 상세한 클래스를 만드는 느낌이다. Memory에 Member를 저장하는 MemoryMemberRepository 클래스를 MemberRepository 인터페이스를 implements해서 만든다
//MemberRepository.java
public interface MemberRepository {
Member save(Member member);
Optional<Member> findByID(int id);
Optional<Member> findByName(String name);
List<Member> findAll();
}
//MemoryMemberRepository.java
public class MemoryMemberRepository implements MemberRepository {
private static Map<Integer, Member> store = new HashMap<>();
private static int sequence = 0;
@Override
public Member save(Member member) {
member.setId(++sequence);
store.put(member.getId(), member);
return member;
}
@Override
public Optional<Member> findByID(int id) {
return Optional.ofNullable(store.get(id));
}
@Override
public Optional<Member> findByName(String name) {
return store.values().stream()
.filter(member -> member.getName().equals(name))
.findAny();
}
@Override
public List<Member> findAll() {
return new ArrayList<>(store.values());
}
}
3. 회원 리파지토리 테스트
Member가 Memory에 저장이 잘되는지 확인하기 위해서 테스트를 해본다. [프로젝트 - src - test - java - com.그룹.이름] 에서 MemoryMemberRepository가 다 잘 동작하는지 확인할 MemoryMemberRepositroy.java 를 생성한다.
단, 만약 테스트하고 싶은 클래스가 패키지에 들어있다면 test 클래스도 동일한 패키지에 포함되어 있어야 한다
MemoryMemberRepository클래스에 각 함수들의 테스트 함수를 작성한다.
@Test
public void save() {
//임의의 Member 하나 생성
Member member = new Member();
member.setName("kimsujin");
//Member 저장
repository.save(member);
//원래 객체의 id로 찾은 객체 == 원래 객체 ?
Member result = repository.findByID(member.getId()).get();
Assertions.assertEquals(result,member);
}
@Test
public void findByName() {
// Member1 생성 및 저장
Member member1 = new Member();
member1.setName("kimsujin");
repository.save(member1);
// Member2 생성 및 저장
Member member2 = new Member();
member2.setName("leechaewon");
repository.save(member2);
//원래 객체의 이름으로 찾은 객체 == 원래 객체 ?
Member result = repository.findByName("kimsujin").get();
Assertions.assertEquals(result, member1);
}
@Test
public void findAll() {
// Member1 생성 및 저장
Member member1 = new Member();
member1.setName("kimsujin");
repository.save(member1);
// Member2 생성 및 저장
Member member2 = new Member();
member2.setName("leechaewon");
repository.save(member2);
//2개를 저장한뒤 findAll 반환하는 객체들이 2개인지 체크
List<Member> result = repository.findAll();
Assertions.assertEquals(result.size(), 2);
}
MemoryMemberRepository의 테스트 함수들을 각각 테스트하기 위해서 각 테스트 함수 옆 실행버튼(▶)을 누른다 (아래와 같이 결과에 체크표시가 뜨면 테스트가 성공한거다)
4. 테스트 에러 발생⭐
테스트 함수를 하나하나 수행해도 되지만 한꺼번에 모든 테스트 함수들을 수행시킬 수 있다.
위 코드에서 테스트 함수들을 하나하나 실행하면 에러가 뜨지 않지만, 모든 테스트 함수들을 한꺼번에 실행시킬려고 MemoryMemberRepositoryTest 옆 실행버튼(▶)을 눌러 실행시키면 에러가 뜬다.
테스트 함수들은 순서가 정해져 있지 않아서 findAll 함수를 수행 하고 findByName 함수를 수행할 경우 "kimsujin" 이름을 가진 Member 객체가 2개 저장되기 때문에 findByName에서 "kimsujin"을 찾은 결과는 findByName에서 생성한 "kimsujin" 객체와 달라 에러가 발생한다.
그래서 각각의 테스트 함수를 수행한 뒤 저장소는 말끔하게 정리해줘야 한다
//MemoryMemberRepository.java
public void clearStore() {
store.clear();
}
@AfterEach를 붙이면 각 테스트 함수를 수행한 뒤 수행하는 메소드이다
//MemoryMemberRepositoryTest.java
@AfterEach
public void afterEach() {
repository.clearStore();
}
}
성공:)
스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술 - 인프런 | 학습 페이지
지식을 나누면 반드시 나에게 돌아옵니다. 인프런을 통해 나의 지식에 가치를 부여하세요....
www.inflearn.com
'보지마세요' 카테고리의 다른 글
React Document 1 : React란? (0) | 2022.06.02 |
---|---|
Spring 공부하기(3) - 회원 서비스 만들기 (0) | 2022.05.25 |
스프링 부트 (0) | 2022.05.25 |
Spring 공부하기(1) - 웹 개발 기초 (0) | 2022.05.24 |
JSP 공부하기(5) - 게시판 글쓰기 (0) | 2022.05.23 |