
이제 만들어 놓은 회원 서비스 클래스를 테스트 해보자
테스트 대상 클래스에서
ctrl+shift+T를 누르면 자동으로 테스트 클래스를 생성할 수 있다.
테스트케이스를 작성할 때
1. given (주어진 조건)
2. when (검증할 것)
3. then (어떻게 되는지)
의 세 단계를 거쳐 코드를 작성하면 편리하다.
@Test
public void 회원가입() {
//given
Member member = new Member();
member.setName("spring1");
//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("spring1");
Member member2 = new Member();
member2.setName("spring1");
//when
memberService.join(member1);
//then
try {
memberService.join(member2);
fail();
} catch (IllegalStateException e) {
assertThat(e.getMessage()).isEqualTo("이미 존재하는 회원입니다");
}
}
그러나 try-catch구문보다는 assertThrows메소드를 사용하는것이 훨씬 유용하다.
따라서 다음과 같이 수정할 수 있다.
//when
memberService.join(member1);
//then
IllegalStateException e = assertThrows(IllegalStateException.class, () -> memberService.join(member2));
assertThat(e.getMessage()).isEqualTo("이미 존재하는 회원입니다");
assertThrows메소드는 첫번째 인자로 발생할 예외 클래스의 Class 타입을 받고, 두번째 인자로 람다식을 받는다. 람다식에서 예외가 발생할 경우 Class 타입과 발생힌 예외가 같은 타입인지 체크한다.
clear를 해야하는데 여기에는 MemoryMemberRepository 가 없어서 clear를 할 수 없다.MemoryMemberRepository 객체를 만들자!MemoryMemberRepository repository = new MemoryMemberRepository();
@AfterEach
public void afterEach() {
repository.clearStore();
}
하지만 애매한 부분이 있다. 여기서 새로 만든 repository는 MemberService의 객체와 다른 인스턴스이다. (new를 통해 새로 만들었기 때문)
MemberService 클래스와 MemberServiceTest 클래스가 서로 같은 인스턴스를 공유하려면 어떻게 해야할까
private final MemberRepository memberRepository;
//바로 new 를 이용해 인스턴스 생성 X
public MemberService(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
//생성자를 이용해 밖에서 주입
MemoryMemberRepository memberRepository;
@BeforeEach
public void beforeEach() {
memberRepository = new MemoryMemberRepository();
memberService = new MemberService(memberRepository);
}
이렇게 하면 테스트를 실행할 때마다 각각
MemoryMemberRepository가 생성됨
MemoryService입장에서 보면 외부에서MemoryMemberRepository를 주입해줌 --> Dependency Injection (DI:의존성 주입)