티스토리 뷰

Spring

Spring 2

먹태 2020. 10. 13. 19:35

회원관리예제

 

 

회원 객체 

package hello.hellospring.domain;

public class Member {
    private String name;
    private Long id;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }
}

 

-  id, name(이때 id는 시퀀스고 name은 사용자가 등록한 값)

 

 

 

package hello.hellospring.repository;

import hello.hellospring.domain.Member;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Optional;
@Repository
public interface MemberRepository {

    Member save(Member member);
    Optional<Member> findById(Long id);
    Optional<Member> findByName(String name);
    List<Member> findByAll();
}

- 회원 리포지토리 인터페이스 : save(저장), findById(id 조회), findByName(이름찾기), findByAll(전체조회)

 

 

 

회원 리포지토리 구현체

package hello.hellospring.repository;

import hello.hellospring.domain.Member;
import org.springframework.stereotype.Repository;

import java.util.*;
import java.util.stream.Stream;

public class MemoryMemberRepository implements MemberRepository {

    private static Map<Long, Member> store = new HashMap<>();
    private static Long sequence =0L;

    @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));
    }

    @Override
    public Optional<Member> findByName(String name) {
        return store.values().stream()
                .filter(member -> member.getName().equals(name))
                .findAny();
    }

    @Override
    public List<Member> findByAll() {
        return new ArrayList<>(store.values()) ;
    }

    
}

 

 

 

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

package repository;

import hello.hellospring.domain.Member;
import hello.hellospring.repository.MemoryMemberRepository;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;

import java.util.List;
import java.util.Optional;

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

class MemoryMemberRepositoryTest {

    MemoryMemberRepository repository = new MemoryMemberRepository();

    @AfterEach
    public void afterEach(){
        repository.clearStore();
    }

    @Test
    public void save(){
        Member member = new Member();
        member.setName("test");

        repository.save(member);
        Member result = repository.findById(member.getId()).get();
      //  Assertions.assertEquals(member, result);
        assertThat(member).isEqualTo(result);
    }

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

        Member member2 = new Member();
        member2.setName("test2");
        repository.save(member2);

     //   Optional<Member> test2 = repository.findByName("test2");
        Member result = repository.findByName("test1").get();
        assertThat(result).isEqualTo(member1);
    }

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

        Member member2 = new Member();
        member2.setName("test22");
        repository.save(member2);

        List<Member> result = repository.findByAll();
        assertThat(result.size()).isEqualTo(2);
    }

}

- @AfterEach : 각 테스트 실행 후 호출

(사용이유 : 한번에 여러 테스트를 실행하면 메모리 DB에 직전 테스트의 결과가 남을 수 있다.

이렇게 되면 이전 테스트 때문에 다음 테스트가 실패할 가능성이 있다. 여기서는 메모리 DB에 저장된 데이터를 삭제)

테스트는 각각 독립적으로 실행되어야 한다. 테스트 순서에 의존관계가 있는 것은 좋은 테스트가 아니다. 

 

 

 

 

 

회원 서비스 개발

package hello.hellospring.service;

import hello.hellospring.domain.Member;
import hello.hellospring.repository.MemberRepository;
import hello.hellospring.repository.MemoryMemberRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Optional;


public class MemberService {

///    private final MemberRepository memberRepository =  new MemoryMemberRepository();

    private final MemberRepository memberRepository;


    public MemberService(MemberRepository memberRepository) {

        this.memberRepository = memberRepository;
    }

    public Long join(Member member){

//        Optional<Member> result = memberRepository.findByName(member.getName());
//        result.ifPresent(m->{
//            throw new IllegalStateException("존재함");
//        });

        validateDuplicateMember(member); //중복검사
        memberRepository.save(member);
        return member.getId();

    }

    private void validateDuplicateMember(Member member) {
        memberRepository.findByName(member.getName())
               .ifPresent(m->{
                   throw new IllegalStateException("존재함");
               });
    }

    public List<Member> findMember(){
        return memberRepository.findByAll();
    }

    public Optional<Member> findOne(Long memberId){
        return memberRepository.findById(memberId);
    }

}

 

 

* 체크해야될것

public class MemberService {

    private final MemberRepository memberRepository =  new MemoryMemberRepository();
    
    }

- 기존에는 회원 서비스가 메모리 회원 리포지토리를 직접 생성

 

public class MemberService {

///  private final MemberRepository memberRepository =  new MemoryMemberRepository();

    private final MemberRepository memberRepository;

    public MemberService(MemberRepository memberRepository) {

        this.memberRepository = memberRepository;
    }
 }

- 회원 리포지토리의 코드가 회원 서비스 코드를 DI 가능하게 변경한다.

- 메소드로 추출 : ctrl alt m

 

 

 

회원 서비스 테스트

package hello.hellospring.service;

import hello.hellospring.domain.Member;
import hello.hellospring.repository.MemberRepository;
import hello.hellospring.repository.MemoryMemberRepository;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import java.util.Optional;

import static org.assertj.core.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.*;

class MemberServiceTest {
//    MemberService memberService = new MemberService();
//    MemoryMemberRepository memberRepository = new MemoryMemberRepository();

    MemberService memberService;
    MemoryMemberRepository memberRepository;

    @BeforeEach
    public void beforeEach(){
        memberRepository = new MemoryMemberRepository();
        memberService = new MemberService(memberRepository);
    }

    @AfterEach
    public void afterEach(){
        memberRepository.clearStore();
    }

    @Test
    void join() {
        // given 주어졌을때
        Member member = new Member();
        member.setName("test");

        //when 실행이 되고
        Long saveId = memberService.join(member);

        //then 결과가 나온다
        Member findMember = memberService.findOne(saveId).get();
        assertThat(member.getName()).isEqualTo(findMember.getName());

    }

    @Test
    void 중복_test() {
        Member member1 = new Member();
        member1.setName("test");

        Member member2 = new Member();
        member2.setName("test");

        memberService.join(member1);

//        try {
//            memberService.join(member2);
//            fail();
//        } catch (IllegalStateException e){
//            assertThat(e.getMessage()).isEqualTo("존재함2");
//        }

        //예외가 터져야함
        IllegalStateException e = assertThrows(IllegalStateException.class, () -> memberService.join(member2));
        assertThat(e.getMessage()).isEqualTo("존재함");
        //     assertThrows(NullPointerException.class, ()->memberService.join(member2));

    }
    
}

- @BeforeEach : 각 테스트 실행 전에 호출된다. 테스트가 서로 영향이 없도록 항상 새로운 객체를 생성하고, 의존관계도 새로 맺어준다

- 테스트 코드 메소드는 그냥 한글을 써도 괜찮다

- 테스트 코드 생성 : ctrl shift t

- 변수 추출 : ctrl alt v

'Spring' 카테고리의 다른 글

[Spring] 간단한 주문 시스템 예제 - '회원' 도메인 개발, 실행, 테스트  (0) 2021.04.10
Spring 3  (0) 2020.10.19
Spring 1  (0) 2020.10.13
[Spring] DI Annotation 예제  (0) 2018.05.13
[Spring] DI 기본예제 3  (0) 2018.05.13
댓글
최근에 올라온 글
최근에 달린 댓글
링크
Total
Today
Yesterday