Test를 할 때에 아주 편한 단축키가 있다.

그림과 같이 클래스에 ctrl + shift + t를 해주면 Test 생성 창이 뜨는데,
이때 Test 할 메서드를 모두 선택하고 OK를 눌러주면 된다.
이렇게 하면 예쁘게 각 메서드의 Test 껍데기까지 포함해서 Test 클래스가 만들어진다.
package hello.hellospring.service;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class MemberServiceTest {
@Test
void join() {
}
@Test
void findMembers() {
}
@Test
void findOne() {
}
}
그리고, Test 코드를 짤 때 유용한 논리단계가 있는데,
Given(무언가가 주어졌을 때) - When(이것을 실행했을 때) - Then(그러면 결과가 이렇게 나와야 한다.) 문법이다.
@Test
void join() {
//given
//when
//then
}
이렇게 주석을 깔고 하면 편하다.
1. join 메서드 Test
@Test
void join() {
//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());
}
새 Member 객체를 만들고 setName을 한다.
join 메서드는 return 값이 Long Id이기 때문에 이 값을 받는데,
이 받은 Id에 해당되는 Member 객체가 getName을 했을 때 그 멤버와 같느냐
이 과정을 테스트하는 것이다.
그러면 초록 체크표시가 잘 뜬다.

BUT!!! Test에서는 예외 플로우가 매우 중요하므로 위 경우는 반쪽짜리 테스트이다.
1-2. ValidateDuplicateMember() 메서드 Test
@Test
public void ValidateDuplicateMember(){
//given
Member member1 = new Member();
member1.setName("Spring");
Member member2 = new Member();
member2.setName("Spring");
//when
memberService.join(member1);
try{
memberService.join(member2);
fail();
} catch(IllegalStateException e){
assertThat(e.getMessage().isEqualTo("이미 존재하는 회원입니다."));
}
//then
}
Member 객체를 두 개 만들고, 둘 다 이름을 동일하게 설정한다.
이때 member1이 join한 후, member2의 join을 try-catch문으로 나타낸다.
MemberService에서 뜨도록 설정한 텍스트가 e의 메세지와 일치하면 성공.
초록 체크가 잘 뜬다.

그런데 텍스트로 뜨는 것보다는 다른 방법이 있는데,
assertThrows 함수를 쓰는 방법이다.
assertThrows(이 Exception 이 발생해야 한다.class, () -> 이것을 동작할 때);
//when
memberService.join(member1);
assertThrows(IllegalStateException.class, () -> memberService.join(member2));
그러면 IllegalStateException이 잘 떠서 초록 체크표시가 나온다.
또 assertThrows의 장점은 뜬 Exception 메서지를 볼 수 있다는 것인데,
assertThrows(IllegalStateException.class, () -> memberService.join(member2));
이 부분에 ctrl + alt + v 해주면
IllegalStateException e = assertThrows(IllegalStateException.class, () -> memberService.join(member2));
이렇게 자동 리턴이 된다.
//when
memberService.join(member1);
// ctrl+enter+v
IllegalStateException e = assertThrows(IllegalStateException.class, () -> memberService.join(member2));
assertThat(e.getMessage()).isEqualTo("이미 존재하는 회원입니다.");
그리고 이 e에서 getMessage한 값이 "이미 존재하는 회원입니다."인 것이 확인되면,
성공이라고 할 수 있다.
여기에서도 사용한 repository를 clear해줘야,
Test 순서에 국한되지 않고 Test 할 수 있기 때문에 afterEach, clear 해주도록 한다.
MemberService memberService = new MemberService();
// 지금 repository가 존재하지 않기 때문에 아래 코드 추가
MemoryMemberRepository memberRepository = new MemoryMemberRepository();
@AfterEach
// 메서드가 끝날 때마다 이것을 실행
public void afterEach(){
memberRepository.clearStore();
}
clear를 해주고 싶지만 MemberService밖에 없기 때문에,
MemberRepository를 가져온다.
그런데, MemoryMemberRepository 클래스에서 사용하는 MemoryMemberRepository는 이름만 같기 때문에
static이 빠지면 다른 데이터베이스를 사용하는 문제가 될 수 있다.
그렇기 때문에 MemberService.java의 기존 부분을
private final MemberRepository memberRepository = new MemoryMemberRepository();
아래와 같이 바꿔주는 것이 좋다.
MemberRepository를 내가 넣어주는 것이 아닌, 외부에서 넣어주도록 하는 것이다.
private final MemberRepository memberRepository;
public MemberService(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
그리고 MemberServiceTest.java에서
아래 부분을
MemberService memberService = new MemberService();
MemoryMemberRepository memberRepository = new MemoryMemberRepository();
이렇게 @BeforeEach를 사용해 바꿔주면 된다.
@BeforeEach
public void beforeEach(){
memberService = new MemberService(memberRepository);
memberRepository = new MemoryMemberRepository();
}
이렇게 바꿔주면 실행을 할 때마다 @BeforeEach가 실행되어
같은 MemoryMemberRepository 데이터베이스를 사용하게 된다.
(외부에서 MemoryMemberRepository를 넣어주기 때문)
'Framework > Spring' 카테고리의 다른 글
| 자바 코드로 직접 스프링 빈 등록하기 (0) | 2024.01.12 |
|---|---|
| 컴포넌트 스캔, 자동 의존관계 (0) | 2024.01.12 |
| 회원 서비스 개발 (0) | 2024.01.09 |
| 회원 리포지토리 테스트 케이스 작성 (0) | 2024.01.09 |
| 회원 도메인, 리포지토리 만들기 (0) | 2024.01.09 |