📢 김영한님이 지음,
[스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술] 강의를 정리한 글입니다.
💻 회원 서비스 작성
public class MemberService {
private final MemberRepository memberRepository = new MemoryMemberRepository();
// 회원가입
public Long join(Member member) {
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);
}
}
private final MemberRepository memberRepository = new MemoryMemberRepository();
문제가 하나가 발생하는데, 멤버 서비스에 있는 레포지토리랑 테스트에 있는거랑 다른 인스턴스이다.
private final MemberRepository memberRepository;
public MemberService(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
우리는 MemberService 객체를 생성할 때 외부에서 선언된 memberRepository 객체를 주입받아 사용할 수 있게 바꿔줘야 합니다. 이와 같은 디자인 패턴을 의존성 주입이라고 부릅니다.
📢 의존성 주입이란?
- 객체가 의존하는 또 다른 객체를 외부에서 선언하고 이를 주입받아 사용하는 것이다.
- 의존성을 주입하는 방법으로는 객체를 생성할 때 생성자를 통해 전달하는 방식과 Setter() 메소드를 통해 전달하는 방식이 있습니다.
- 의존성 주입을 이용하면 주입받는 대상이 변하더라도 기존 구현자체를 수정할 일이 없어 의존성이 감소합니다. 또한 재사용성이 증가하며 테스트하기 좋은 코드가 됩니다.
💻 회원 서비스 테스트 케이스 작성
작성된 회원 서비스 코드를 테스트하기 위해 /test/java/hello.hellospring/service 라는 패키지를 생성하고 MemberServiceTest.java 라는 파일을 만들어 다음과 같이 작성해줍니다.
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("spring");
//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("이미 존재하는 회원입니다.");
}
}
@BeforeEach
어노테이션을 이용해 각각의 테스트 전에 beforeEach() 메소드를 실행시킵니다. 이를 통해 테스트가 서로 영향이 없도록 항상 새로운 객체를 생성하고 새로 의존성도 주입해줍니다.@AfterEach
어노테이션을 이용하여 각각의 테스트가 끝날 때마다 메모리(DB)에 저장된 데이터를 삭제해줍니다.