회원 서비스 클래스를 테스트해보자
MemberService.java에서 단축키 ctrl + shift + T
를 눌러 테스트 껍데기를 자동생성할 수 있다.
테스트 케이스를 작성할 때는,
// given
// when
// then
이렇게 주석을 달아주면, 훨씬 의미를 파악하기 좋다.
MemverServiceTest.java
class MemberServiceTest {
MemberService memberService = new MemberService();
MemoryMemberRepository memberRepository = new MemoryMemberRepository();
@AfterEach
public void afterEach(){
memberRepository.clearStore(); // 테스트 하나 끝날 때마다 DB의 값을 날려줌
}
@Test
void 회원가입() {
// "저장한 게 리포지토리에 있는게 맞니?" 를 테스트
//given
Member member = new Member();
member.setName("장서연");
//when
Long saveId = memberService.join(member);
// then
Member findMember = memberService.findOne(saveId).get();
Assertions.assertThat(member.getName()).isEqualTo(findMember.getName());
}
@Test
public void 중복_회원_예외(){
//given
Member member1 = new Member();
member1.setName("장서연");
Member member2 = new Member();
member2.setName("장서연");
//when
memberService.join(member1);
assertThrows(IllegalStateException.class, () -> memberService.join(member2));
/*
try {
memberService.join(member2);
fail();
} catch (IllegalStateException e) {
Assertions.assertThat(e.getMessage()).isEqualTo("이미 존재하는 회원입니다");
}
*/
//then
}
@Test
void findMembers() {
}
@Test
void findOne() {
}
}
그런데, 좀 거슬리는 부분이 있다.
MemberService.java
public class MemberService {
// 회원 서비스를 만드려면, 리포지토리가 당연히 있어야 할 것!
private final MemberRepository memberRepository = new MemoryMemberRepository();
...
}
MemberService.java 에서 new 로 MemoryMemberRepository 를 생성하는 것을 볼 수 있는데,
분명 MemberServiceTest.java 에서도 new 로 MemoryMemberRepository 를 생성해주었다.
다행히 static 으로 설정해주어 별 문제는 되지 않았지만, (static 은 인스턴스별로 생성되는 것이 아닌, 클래스 자체의 변수)
지금 이 상황에서는 MemberService 의 memberRepository와 MemberServiceTest의 memberRepository 는 현재 서로 다른 객체인 상태이다... new 로 또 객체를 생성할 필요가 전혀 없음... 또 해서도 안됨. 당연히 같은 repository로 테스트를 해야하기 때문
어떻게 이를 해결해야 할까?
지금 문제를 정리해보자면,
MemberService 에서 생성한 memberRepository와 MemberServiceTest의 memberRepository 는 현재 서로 다른 인스턴스라는 것이다. 현재는 static 으로 선언되어있기 때문에 에러는 발생하지 않지만, static 이 아니면 DB가 다른 DB가 되면서 문제가 생길 것이다.
어떻게 하면 같은 인스턴스를 쓰게 할 수 있을까?
이렇게 하면, 같은 repository 를 사용할 수 있게 된다.
MemberService 입장에서, 직접 new 하지 않는다. 외부에서 memberRepository 를 넣어준다.
이것을 의존성주입(Dependency Injection)이라고 한다.