안녕하세요 jju_developer입니다.
이번시간에는 지난 시간에 코딩한 회원과 저장소가 잘 작동을 하는지 테스트를 해보겠습니다.
[스프링부트] 개발 전 테스트 회원 도메인과 리포지토리 생성 02
안녕하세요 jju_developer입니다.😄 지난 시간에 이어서 진행을 하도록 하겠습니다. [스프링부트] 개발 전 테스트 요구사항 정리 01 안녕하세요 jju_developer입니다. 혼자 개인 프로젝트를 하다가 스프
jju240.tistory.com
<지난시간 기본 내용>
1. domain -> Member(class)
*Member class에 id, name 이 있습니다.
2. repository -> MemberRepository(interface)
2-1. 회원 저장 기능 => save
2-2. 아이디 찾기 => findById
이름 찾기 => finaByName
전체 회원 찾기 => findAll
3. repository -> MemoryMemberRepository(implements class)
MemberRepository의 기능을 구현한 구현 클래스 생성
3-1. 회원 저장 기능 구현 => save(Member member)
store.put(member.getId(), member);
//맵형태의 store를 하나 만들고 거기에 회원 아이디와 회원 이름을 저장합니다.
3-2. 아이디 찾기 구현 => findById
//return store.get(id);
이름 찾기 구현 => finaByName
//member.getName().equals(name) 같으면 findAny()로 찾아옴
전체 회원 찾기 구현 => findAll
//return new ArrayList<>(store.values());
여기까지 지난 시간에 작성한 내용입니다!
이제는 본격적으로 이렇게 구현한 코드들이 잘 작동을 하는지 여부에 대해 검사를 해보겠습니다.
보통은 테스트를 할 때 자바의 메인 메서드를 통해서 실행을 하거나, 컨트롤러에서 해당 기능을 실행하여서
테스트를 했는데 이렇게 하게 된다면 시간이 너무 많이 소요되고, 반복적으로 실행을 하기 어렵기 때문에
자바에서는 제이유닛이라는 프레임워크로 테스트를 진행합니다.
이번에도 JUnit으로 테스트를 실행해 보도록 하겠습니다.
1. scr/test/java 폴더에 테스트 코드 생성
테스트 코드 작성합니다.
package org.project.whipping.repository;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.project.whipping.domain.Member;
public class MemoryMemberRepositoryTest {
MemberRepository repository = new MemoryMemberRepository();
//@test 에노테이션을 쓰면 해당 메소드를 실행해볼 수 있당.
@Test
public void save(){
Member member = new Member();
member.setName("spring");
repository.save(member);
Member result = repository.findByID(member.getId()).get();
//repository.findByID(member.getId()); Optional에서 값을 꺼낼때에는
//.get()으로 바로 꺼낼수도 있습니다.
//repository.findByID(member.getId()).get();얘들을 result에 담아보겠습니다.
//Member result = repository.findByID(member.getId()).get();
//System.out.println("result = "+(result == member));
Assertions.assertEquals(member,result);
}
}
실행하면 오류 없이 잘 테스트가 된 것을 알 수 있습니다.
여기서 만약에
내가 Assertions.assertEquals(member,result);
member에 저장된 값과 result에 담은 값이 다르게 null값이 들어있게 하면 어떤 결과가 나올까요?
이렇게 null값을 넣어서 비교를 하면 테스트 코드가 에러가 뜨는 것을 볼 수 있습니다.
위에 에러 코드를 보면 Expected 값은 : 뒤에 오는 값인데 Actual이 : null로 들어왔다는 내용입니다.
다른 방법으로 테스트하려면 Assertions assertj를 쓰면 됩니다.
Assertions.assertThat(member).isEqualTo(result);
//멤버가 리절트랑 같니?
요런 문법을 사용해서 테스트를 할 수도 있습니다.
참 테스트 하나도 다양한 방법이 있죠?
본인에게 맞는 문법을 사용해서 테스트문을 작성하시면 됩니다.
저는 앞으로 Assertions that문장을 사용하려 합니다.
보기에 더 간단해 보입니다!
또한 앞에 Assertions는 스테틱 import를 하여 바로
import static org.assertj.core.api.Assertions.*;
assertThat(member).isEqualTo(result);
요렇게 간단하게 사용이 가능합니다!
참 쉽죵?
이번에는 finaByName을 테스트해보겠습니다.
@Test
public void findByName(){
//회원1,회원2에 이름을 각각 넣겠습니다.
Member member1 = new Member();
Member member2= new Member();
member1.setName("jju");
member2.setName("developer");
repository.save(member1);
repository.save(member2);
//회원 1 과 jju를 넣고 그 값과 일치하는지 보겠습니다.
//그럼 회원1을 잘 꺼내온것이죠
Member result= repository.findByName("jju").get();
//Optional<Member> result= repository.findByName("jju");
assertThat(result).isEqualTo(member1);
}
저는 이 부분을 사실 각각 회원 1과 회원 2를 만들어 놓고 멤버의 이름을 각각 세팅 후!
repository.save(member1);
repository.save(member2);
저장소에 멤버를 저장하는 것을 까먹고 놓쳐가지고
왜 자꾸 repository,findByName할때 오류가 나지? 했었는데
저장소에 저장된 객체가 없어서 계속 오류가 났었습니다.
아무튼 저장소에다가 회원 1과 2를 저장한 뒤에
저장소에 jju라는 아이가 있니?라고 물어보고 result에 담은 다음에
assertThat을 활용해서 내가 물어본 jju와 member1에 담긴 사람이 같으면 오류 없이 테스트가
통과되는 것을 볼 수 있습니다~!!!
여기까지 따라오셨으면 정말 잘하신 것입니다.
(여기서 팁! //Optional<Member> result= repository.findByName("jju"); 이 부분을
그냥 .get()을 해주면 Optional이라고 안 하고 그냥 사용 가능합니다.)
이렇게 각각의 테스트를 만든 다음에 class에 있는 테스트를 돌려보면
여러 테스트를 한 번에 작동이 가능합니다~!
이제는 findAll이 잘 작동하는지 테스트를 해보도록 하겠습니다~!!
아까와 같은 방식으로 우선 리포지토리에 멤버를 저장해 보겠습니다.
이번에는 3명의 회원을 저장해 보겠습니다~!
@Test
public void findAll(){
//3명의 회원을 만들겠습니다.
Member member1 = new Member();
Member member2 = new Member();
Member member3 = new Member();
member1.setName("jju");
member2.setName("developer");
member3.setName("jjang");
repository.save(member1);
repository.save(member2);
repository.save(member3);
List<Member> result = repository.findAll();
assertThat(result.size()).isEqualTo(3);
//List에 3명이 담겼니?
}
회원 1 = 쮸
회원 2 = 디벨롭퍼
회원 3 = 짱
을 담고 아까처럼 저장소에 save를 했습니다.
그다음에 우리가 만들어 놓았던 finaAll 메서드를 실행했을 때
그 결과를 result에 담고 사이즈가 3일 테니까 그게 isEqualTo(3)이랑 같니?
라고 물어봤을 때 정상적으로 초록이가 뜨게 됩니다!
어떠세요?
이해가 가시나요?
assertThat(result.size()).isEqualTo(3); 요기에
assertThat(result.size()).isEqualTo(다른숫자); 다른 숫자를 넣게 되면 에러가 납니다!!
자, 이제 (중요✨✨✨✨✨)
앞에서 말씀드린 테스트 클래스를 한 번에 전체 작동을 해보겠습니다.
그럼 당연히 앞에서 만든 3개의 테스트가 정상적으로 통과가 되었으니까!
전체 테스트 코드를 돌리면 오류가 없이 나와야 하는데 오류가 납니다!
그 이유가 무엇일까요?!
그 이유는 바로 위 이미지에서 보듯이 테스트는 무작위 순서로 이루어지게 됩니다.
즉 위에서 테스트가 finaAll이라는 메서드가 먼저 테스트가 진행이 되었고 그다음이 이름 찾기... 순으로
(순서 의존적으로 코드를 짜면 안 됩니다!!)
테스트가 진행이 되기 때문에 하나의 테스트가 끝이 나면 반드시 데이터를 clear 해주어야 합니다.
테스트가 하나 끝날 때마다 데이터를 지워주는 메서드를 만들어주어야 합니다.
1. MemoryMemberRepository에 저장소에 저장된 데이터를 지우는 메서드 추가 작성
public void clearStore(){
store.clear();
}
2. MemoryMemberRepositoryTest에 콜백함수 AfterEach생성
public class MemoryMemberRepositoryTest {
MemoryMemberRepository repository = new MemoryMemberRepository();
//MemberRepository repository = new MemoryMemberRepository();
@AfterEach
public void afterEach(){
//콜백
repository.clearStore();
}
콜백메서드!
@AfterEach
이렇게 작성을 다 하고 다시 전체 실행을 해보겠습니다!!!
정상적으로 실행됩니다🌟🌟🌟
저는 이번에 하나하나 코드를 따라가 보면서 이렇게 테스트를 하는구나 하고
알아봤습니다.
여러 개발자분들이 작성한 코드를 테스트를 해야 한다고 강조를 계속해주셔서
저도 개발을 하는 것에만 목적을 두는 것이 아니라,
이 코드가 정상적으로 작동이 되는지도 같이 보면서 하려고 노력 중입니다!
여러분도 지난 포스팅과 이번 포스팅을 비교해 가면서 직접 코드를 짜보시고
테스트를 해보시면 더욱 이해가 가실 겁니다!
3시간 순삭 가~능~
<마무리 중요 내용>
1. 개발 먼저 -> 테스트 후 항상 테스트 데이터 지우기!
순서를 뒤집으면...?
2. 테스트 먼저 만들어 놓고 -> 개발
미리 검증할 수 있는 틀을 만들어 놓는 것
=> 테스트 주도개발 TDD(test-driven development)
저는 1번으로 진행했습니다~ㅎㅎ
오늘도 고생하셨습니다!
'☞Project > 휘핑크림' 카테고리의 다른 글
[스프링부트] 개발 전 회원 서비스 테스트 05 (0) | 2023.03.23 |
---|---|
[스프링부트] 개발 전 테스트 회원 서비스 개발 작성04 (0) | 2023.03.23 |
[스프링부트] 개발 전 테스트 회원 도메인과 리포지토리 생성 02 (2) | 2023.03.23 |
[스프링부트] 개발 전 테스트 요구사항 정리 01 (0) | 2023.03.23 |
[개인 프로젝트 01일차] 스프링 부트 초기 설정 개발환경 만들기!!+마이바티스+인텔리제이 (0) | 2023.03.21 |