회원 관리, Test

Haechan Kim·2022년 7월 6일
0

Spring

목록 보기
4/68
post-custom-banner
  • 일반적 웹 어프리케이션 계층 구조 (MVC)

  • 컨트롤러 -> 서비스 -> 리포지토리 -> DB

  • 회원 도메인
    Member.java

// entity: 데이터 저장 및 관리 테이블
// attribute: entity의 한 부분. column
// 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;
    }
}
  • 클래스 의존 관계

회원 레파지토리를 인터페이스로 만들고 구현체에 CRUD 기능 구현하고 이를 DI(의존성 주입 Dependency Injection).

  • MemberRepository.java
// 레파지토리 - 인터페이스
// 구현체 - MemoryMemberRepository
public interface MemberRepository {
    Member save(Member member); // 회원 저장 후 저장 회원 반환
    Optional<Member> findById(Long id); // id로 회원 조회
    Optional<Member> findByName(String name); // null 반환 대신 Optional로 감싸서 나감.
    List<Member> findAll(); // 저장된 모든 회원 리스트 반환
}
  • MemoryMemberRepository.java
// MemberRepository 인터페이스에 대한 메모리 구현체
public class MemoryMemberRepository implements MemberRepository { // alt+enter로 implement method

    private static Map<Long, Member> store = new HashMap<>();
    private static long sequence = 0L; // 키값 생성 용. 0,1,2,,

    @Override
    public Member save(Member member) {
        member.setId(++sequence);
        store.put(member.getId(), member);
        return member;
    }

    @Override
    public Optional<Member> findById(Long id) {
        return Optional.ofNullable(store.get(id)); // null인 경우 Optional로 감싸서 리턴
    }

    @Override
    public Optional<Member> findByName(String name) {
        return store.values().stream() // 자바8 람다
                .filter(member -> member.getName().equals(name)) // 멤버 getName이 파라미터로 넘어온 name과 같은지 확인. 같은 경우만 필터링 됨
                .findAny(); // 하나라도 찾기. 없으면 null
    }

    @Override
    public List<Member> findAll() { // 실무에선 list 많이 씀
        return new ArrayList<>(store.values());
    }

    public void clearStore() {
        store.clear();
    }
}
  • 테스트 케이스 작성

테스트 시 자바의 main 메서드를 통하거나 웹 애플리케이션의 컨트롤러 사용은 반복 실행 어렵고 여러 테스트 한번에 실행하기 어렵다는 단점 있다.

JUnit 프레임워크로 테스트 실행해 이러한 문제를 해결한다.

  • 회원 레파지토리 메모리 구현체 테스트
    src/test/java/hello/hellosring/repository/MemoryMemberRepositoryTest.js
package hello.hellospring.repository;

import hello.hellospring.domain.Member;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;

import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;

class MemoryMemberRepositoryTest { // 다른곳에서 가져다 쓸 것 아니기 때문에 굳이 public 안해도 됨
    MemoryMemberRepository repository = new MemoryMemberRepository();

    // 테스트 순서는 보장 안됨. 따라서 테스트 하나 끝날 때마다 리파지토리 깔끔하게 지워야함

    @AfterEach
    public void afterEach() { // 테스트 메서드들 끝날때마다 동작. 콜백 메소드
        repository.clearStore();
    }

    @Test
    public void save() { // 만들어둔 save가 동작하는지 보면 됨
        Member member = new Member();
        member.setName("spring");

        repository.save(member);
        Member result = repository.findById(member.getId()).get(); // 반환 타입이 Optional일 때 값 꺼낼때는 get() 사용
        // System.out.println("result = " + (result == member)); // result = true
        //Assertions.assertThat(member).isEqualTo(result);
        assertThat(member).isEqualTo(result); // Assertions에서 ant+enter 누르고 static import 하면 Assertions 안써도 됨
    }

    @Test
    public void findByName() {
        Member member1 = new Member();
        member1.setName("spring1");
        repository.save(member1);

        Member member2 = new Member(); // shift+f6 하면 같은 변수명 전체 바꾸기
        member2.setName("spring2");
        repository.save(member2);

        Member result = repository.findByName("spring1").get();// ctrl+alt+v 하면 리턴값 맞춰서 반환 변수 자동 추가
        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);
    }
}
post-custom-banner

0개의 댓글