반응형
MemberRepository TestCode?
개발한 기능을 실행해서 테스트할 때 자바의 main 메서드를 실행하거나, 웹 애플리케이션의 controller를 통해서 해당 기능을 실행한다. 이러한 방법은 준비하고 실행하는데 시간이 오래 걸리고, 반복 실행이 어렵다. 또한 여러 테스트를 한 번에 실행하기 어렵다는 단점이 있다. java는 JUnit이라는 프레임워크로 테스트를 실행해서 이러한 문제를 해결한다.
Save 기능 Test
test code 작성할 파일이 repository 패키지에 MemoryMemberRepository이기 때문에 뒤에 Test만 붙여서
test/java에 repository 패키지 생성 -> MemoryMemberRepositoryTest.java를 생성해줍니다.
// MemoryMemberRepositoryTest.java ... MemberRepository repository = new MemoryMemberRepository(); @Test // 테스트 코드 작성을 위한 어노테이션 public void save() { // save 기능 테스트 Member member = new Member(); member.setName("spring"); // 임의로 spring 이라는 name을 넣어줌 repository.save(member); Member result = repository.findById(member.getId()).get(); Assertions.assertThat(member).isEqualTo(result); // import org.assertj.core.api.Assertions; // member와 result 값이 같은지 확인 } ...
Assertions에 블록지정하고 option + Enter 키를 입력하시면 Add on demand static import....이라는 메뉴가 있습니다. 그걸 누르시면 assertThat 만 입력해도 사용이 가능합니다.
2번째 이미지를 보시면 import org.assertj.core.api.Assertions; 이 비활성화되고 import static org.assertj.core.api.Assertions.*; 이 활성화된 걸 보실 수 있습니다. 그렇게 되면 3번째 이미지처럼 Assertions이 사라지고 바로 assertThat 사용이 가능합니다.
findByName 기능 Test
이름으로 찾는 기능을 테스트 하기 위해서 임의로 이름을 등록해 줍니다.
// MemoryMemberRepositoryTest.java ... @Test public void findByName() { Member member1 = new Member(); member1.setName("spring1"); // member1이라고 만들고 거기에 spring1 이라는 이름을 세팅해준다. repository.save(member1); // 테스트를 위해서 repository에 저장한다. } ...
좀 더 확실한 테스트를 위해서 spring2를 만들 건데요
복사 붙여 넣기 후 이름만 변경 해 주시면 됩니다.
nember1을 블록 지정해서 shift + F6 단축키를 누르시면 이름 변경 기능이 있습니다.
member2라고 이름을 변경하면 밑에 member1이었던 이름이 member2로 변경된 걸 보실 수 있습니다.
그럼 이제 테스트 코드를 입력하겠습니다.
// MemoryMemberRepositoryTest.java ... @Test public void findByName() { Member member1 = new Member(); member1.setName("spring1"); repository.save(member1); Member member2 = new Member(); member2.setName("spring2"); repository.save(member2); Member result = repository.findByName("spring1").get(); assertThat(result).isEqualTo(member1); } ...
findAll() 기능 Test
// MemoryMemberRepositoryTest.java ... @Test public void findAll() { Member member1 = new Member(); member1.setName("spring1"); repository.save(member1); Member member2 = new Member(); member2.setName("spring2"); repository.save(member2); // 아까 전과 마찬가지로 2개정도 테스트를 진행해봅니다. repository.findAll(); } ...
마지막 구문에 repository.findAll()까지 작성하고 option + command + V (표현식)를 누르시면 List <Member>로 바뀝니다. 저기서 all을 result 등으로 변경해서 코딩을 하셔도 됩니다.
// MemoryMemberRepositoryTest.java ... @Test public void findAll() { Member member1 = new Member(); member1.setName("spring1"); repository.save(member1); Member member2 = new Member(); member2.setName("spring2"); repository.save(member2); List<Member> result = repository.findAll(); assertThat(result.size()).isEqualTo(2); // 2개의 값이 들어있는게 맞는지 확인 } ...
여기까지 현재 구현한 기능은 모두 테스트를 해 보았습니다.
class 실행 시 전체 테스트가 가능하지만 오류가 발생한다?
class를 실행하면 구현한 전체 test 가 실행됩니다.
하나씩 실행했을 때는 제대로 실행이 되었는데 한 번에 실행하니 오류가 발생했습니다.
findAll() Test가 먼저 실행되었기 때문에 이미 값이 들어가 있어서 findByName()이 오류가 발생했습니다.
제대로 실행하려면 변경할 부분이 몇 가지 있습니다.
테스트는 순서와 상관없이(의존관계 없이) 실행될 수 있게 설계가 되어야 합니다.
그러기 위해서는 하나의 테스트가 끝날 때마다 저장소나 공용 데이터들을 깨끗하게 지워줘야 합니다. 그래야 아무런 문제가 없이 잘 실행되는 것을 보실 수 있습니다.
// MemoryMemberRepositoryTest 수정 package repository; import hellospring.hello.domain.Member; import hellospring.hello.repository.MemberRepository; import hellospring.hello.repository.MemoryMemberRepository; import org.junit.jupiter.api.Test; import java.util.List; import static org.assertj.core.api.Assertions.*; public class MemoryMemberRepositoryTest { MemberRepository repository = new MemoryMemberRepository(); //!! MemberRepository -> MemoryMemberRepository로 변경 //!! 코드 추가 @AfterEach public void afterEach() { repository.clearStore(); } //!! 여기까지 추가 // 하나의 Test가 끝날 때마다 저장소를 깨끗이 비워줍니다. @Test // 테스트 코드 작성을 위한 어노테이션 public void save() { Member member = new Member(); member.setName("spring"); repository.save(member); Member result = repository.findById(member.getId()).get(); assertThat(member).isEqualTo(result); } @Test public void findByName() { Member member1 = new Member(); member1.setName("spring1"); repository.save(member1); Member member2 = new Member(); member2.setName("spring2"); repository.save(member2); Member result = repository.findByName("spring1").get(); assertThat(result).isEqualTo(member1); } @Test public void findAll() { Member member1 = new Member(); member1.setName("spring1"); repository.save(member1); Member member2 = new Member(); member2.setName("spring2"); repository.save(member2); List<Member> result = repository.findAll(); assertThat(result.size()).isEqualTo(2); } }
// MemoryMemberRepository // 마지막 구문에 추가 ... public void clearStore() { store.clear(); } ... // 저장소를 비워주는 코드입니다.
TDD (테스트 주도 개발)라고
틀(테스트)을 먼저 만들고 구현 클래스를 만들어서 실행이 잘 되는지 확인해보는 방법도 있습니다.
혼자 아주 소규모의 개발을 할 때를 제외하고는 테스트코드가 없이 개발 하는 것은 불가능하다고 볼 수 있습니다.
테스트코드 관련해서는 정말 깊이 있게 공부하기를 추천합니다.
반응형
'programming > SpringBoot' 카테고리의 다른 글
다시 공부) 스프링부트와 AWS로 혼자 구현하는 웹서비스 (0) | 2022.08.01 |
---|---|
[spring] 회원 서비스 (회원 가입하기, 조회하기) (0) | 2022.07.05 |
[Spring] 스프링 입문강의 3 (회원 관리 예제) (0) | 2022.06.25 |
[Spring] 스프링 입문 강의 2 (콘텐츠의 종류 - 정적 콘텐츠, MVC, API) (0) | 2022.06.24 |
[Spring] 스프링 입문 강의 1 (김영한님 무료 강좌) (0) | 2022.06.16 |