스프링 입문3 (코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술)(feat.김영한 강사님)

권영태·2023년 5월 2일
0

스프링

목록 보기
3/18

Project : Gradle-Groovy Project
JDK : JAVA 17
Spring Boot Version : 3.0.6
Dependencies : Spring Web, Thymeleaf, H2database
IDEA : IntelliJ IDEA

이번 시간에는 회원 도메인과 리포지토리를 구현하고, 이를 테스트한다.

  • 클래스 의존관계는 다음과 같고, 데이터베이스가 결정되지 않아 인터페이스로 설계한다.

👤 회원 도메인

public class Member {

 private Long id;	// 시스템 상에서 저장하는 PK
 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;
 }
}

📁 회원 리포지토리 인터페이스

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

findByID가 만약 Null 값으로 찾아질 때 Null을 Optional로 감싸 반환

📂 회원 리포지토리 구현체

public class MemoryMemberRepository implements MemberRepository {

 private static Map<Long, Member> store = new HashMap<>();
 private static long sequence = 0L;	// key값처럼 0,1,2 등등 생성
 
 @Override
 public Member save(Member member) {
 	member.setId(++sequence); // Memeber Id값 setting
 	store.put(member.getId(), member);
 	return member;
 }
 
 @Override
 public Optional<Member> findById(Long id) {
 	return Optional.ofNullable(store.get(id));
 }
 
 @Override
 public List<Member> findAll() {
 	return new ArrayList<>(store.values());
 }
 
 @Override
 public Optional<Member> findByName(String name) {
 	return store.values().stream()
 			.filter(member -> member.getName().equals(name))
 			.findAny();
 }
 
 public void clearStore() {
 	store.clear();
 }
}

개발한 기능들을 테스트할 때 main 메서드를 통해 테스트하거나, 웹 애플리케이션의 컨트롤러를 통해 해당 기능들을 테스트한다.
이는 오래 걸리고 여러 테스트를 진행하기 어렵다.
그래서 자바는 JUnit을 이용해 테스트를 진행한다.

💡JUnit

  • JUnit은 자바 프로그래밍 언어용 유닛 테스트 프레임워크로써
    assert 메서드로 테스트 케이스의 수행 결과를 판별한다.
    • 유닛 테스트는 모든 함수ㆍ메서드에 대한 테스트 케이스를 작성하여
      정상 작동하는지 검증하는 절차로 'System.out.println()'으로 하는 번거로운 디버깅이 없어 디버깅 시간이 단축된다.

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

class MemoryMemberRepositoryTest {

MemoryMemberRepository repository = new MemoryMemberRepository();

 @AfterEach
 public void afterEach() {
 	repository.clearStore();
 }
 
 @Test
 public void save() {
 	//given
 	Member member = new Member();
 	member.setName("spring");
 
 	//when
 	repository.save(member);
 
 	//then
 	Member result = repository.findById(member.getId()).get();
 	assertThat(result).isEqualTo(member);
 }
 
 @Test
 public void findByName() {
 	//given
 	Member member1 = new Member();
 	member1.setName("spring1");
 	repository.save(member1);
 	Member member2 = new Member();
 	member2.setName("spring2");
 	repository.save(member2);
 
 	//when
 	Member result = repository.findByName("spring1").get();
 
 	//then
 	assertThat(result).isEqualTo(member1);
 }
 
 @Test
 public void findAll() {
 	//given
 	Member member1 = new Member();
 	member1.setName("spring1");
 	repository.save(member1);
 	Member member2 = new Member();
 	member2.setName("spring2");
 	repository.save(member2);
 
 	//when
 	List<Member> result = repository.findAll();
 
 	//then
 	assertThat(result.size()).isEqualTo(2);
 }
}

위 코드에서 기본 어노테이션을 간단하게 알아보자.
1. @Test : 테스트를 만드는 모듈 역할
2. @BeforeEach : 각 테스트 메서드 전에 실행
3. @AfterEach : 각 테스트 메서드 후에 실행

  • 한번에 여러 테스트를 실행하면 메모리 DB에 직전 테스트 결과가 남아 다음 테스트가 실패할 수 있다. @AfterEach를 사용해 afterEach() 메서드를 만들면 각 테스트가 종료될 때마다 실행되어 메모리 DB에 저장된 데이터를 삭제한다.
  • 테스트는 독립적으로 실행되야 하며 순서 의존관계가 있는건 좋은 테스트가 아니다.
profile
GitHub : https://github.com/dudxo

0개의 댓글