package hello.hellospring.controler;
import hello.hellospring.service.MemberService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@Controller
public class MemberController {
private final MemberService memberService;
@Autowired
public MemberController(MemberService memberService){
this.memberService = memberService;
}
}
2. Service등록
@Autowired로 MemberController가 MemberService를 인자로 받아들이는데 이를 위해서는 memberService가 서비스로 등록이 되어있어야 합니다. 따라서 memberService에 아래와 같이 @Service 애노테이션을 붙여줍니다. 그리고 내부에 MemberService 메서드는 @Autowired로 다시 등록합니다.
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;
@Service
public class MemberService {
private final MemberRepository memberRepository;
@Autowired
public MemberService(MemberRepository memberRepository){
this.memberRepository = memberRepository;
}
/*
회원 가입
*/
3. Repository등록
마찬가지로 @Autowired로 MemberService가 MemberRepository를 인자로 받아들이는데 해당하는 인자인 MemorymemberRepository클래스를 Repository로 등록해주어야 합니다.
package hello.hellospring.repository;
import hello.hellospring.domain.Member;
import org.springframework.stereotype.Repository;
import java.util.*;
@Repository
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;
}
Service 클래스에 대한 Test클래스를 작성하겠습니다. 우선 Service 클래스의 소스코드에서 Ctrl+Alt+T 버튼을 누르면 아래와 같이 테스트 코드 생성창이 뜹니다.
Create New Test를 클릭하면 아래의 세부 설정창이 뜨는데, 아래와 같이 Testing Library를 JUnit5로 선택하고, Member들을 체크해준 뒤 OK를 클릭합니다.
그럼 자동으로 기본 구성이 된 소스 코드가 Test패키지 하위에 나타나게 됩니다. 해당 클래스 MemberServiceTest에 코드를 작성하면 됩니다.
MemberServiceTest
package hello.hellospring.service;
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.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.*;
class MemberServiceTest {
MemberService memberService;
MemoryMemberRepository memberRepository;
@BeforeEach
public void beforeEach(){
memberRepository = new MemoryMemberRepository();
memberService = new MemberService(memberRepository);
}
//매번 메모리 클리어
@AfterEach
public void afterEach(){
memberRepository.clearStore();
}
@Test
void 회원가입() {
//given
Member member = new Member();
member.setName("hello");
//when
Long saveId = memberService.join(member);
//then
Member findMember = memberService.findOne(saveId).get();
assertThat(member.getName()).isEqualTo(findMember.getName());
}
@Test
public void 중복_회원_예외(){
//given
Member member1 = new Member();
member1.setName("spring");
Member member2 = new Member();
member2.setName("spring");
//when
memberService.join(member1);
IllegalStateException e = assertThrows(IllegalStateException.class, () -> memberService.join(member2));
assertThat(e.getMessage()).isEqualTo("이미 존재하는 회원입니다.");
/*
try{
memberService.join(member2);
fail();
}catch(IllegalStateException e){
assertThat(e.getMessage()).isEqualTo("이미 존재하는 회원입니다.111");
}
*/
//then
}
@Test
void findMembers() {
}
@Test
void findOne() {
}
}
@BeforeEach부분을 보면 memberRepository를 생성하고 이를 MemberService에 인자로 넘겨주도록 하였습니다. 이렇게 하면 New로 생성할 경우, 실제 서비스에서 생성하던 것과는 별개의 객체가 만들어지던 것을 방지할 수 있는데, 이를 Dependancy Injection이라고 합니다. 이렇게 구성하려면 우선 MemberSevice 객체 선언 부분도 수정을 해줘야 합니다.
MemberService
MemberService 객체 생성부분만 표시하도록 하겠습니다.
public class MemberService {
private final MemberRepository memberRepository;
public MemberService(MemberRepository memberRepository){
this.memberRepository = memberRepository;
}
/*
회원 가입
*/
Service를 구현합니다. hello.hellospring하위에 Service 패키지를 만들고 MemberService클래스를 추가합니다.
1. MemberService클래스
package hello.hellospring.service;
import hello.hellospring.domain.Member;
import hello.hellospring.repository.MemberRepository;
import hello.hellospring.repository.MemoryMemberRepository;
import java.util.List;
import java.util.Optional;
public class MemberService {
private final MemberRepository memberRepository = new MemoryMemberRepository();
/*
회원 가입
*/
public Long join(Member member){
// 같은 이름이 있는 중복회원 x
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> findMembers(){
return memberRepository.findAll();
}
public Optional<Member> findOne(Long memberId){
return memberRepository.findById(memberId);
}
}
메서드 validateDuplicateMember(Member member) 부분은 Join 메서드 내부에서 구현했던 부분인데, Method Extraction이라는 기능으로 외부 함수로 꺼내왔습니다. 단축키는 Alt+Shift+T입니다.
테스트 케이스를 만들고 테스트를 해보겠습니다. 아래와 같이 테스트 패키지-hello.hellospring 패키지 아래에 repository패키지와 MemoryMemberRepositoryTest클래스를 구성합니다.
1. MemoryMemberRepositoryTest클래스
package hello.hellospring.repository;
import hello.hellospring.domain.Member;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
public class MemoryMemberRepositoryTest {
MemoryMemberRepository repository = new MemoryMemberRepository();
@AfterEach
public void afterEach(){
repository.clearStore();
}
@Test
public void save(){
Member member = new Member();
member.setName("spring");
repository.save(member);
Member result = repository.findById(member.getId()).get();
//Assertions.assertEquals(member, null); (기대값, 실제값)
assertThat(member).isEqualTo(result); //(기대값, 실제값)
}
@Test
public void indByName(){
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);
}
}