이제 만들어 놓은 회원 서비스 클래스를 테스트 해보자
테스트 대상 클래스에서
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:의존성 주입)