지금까지는 순수한 자바 코드로 테스트를 했는데 이제는 DB도 연결하고 해야 하니까 스프링을 띄워서 테스트 해보려고 한다!!
우선 test/service/ 하단에 MemberServiceIntegrationTest 를 만들어준다.
@SpringBootTest
@Transactional
class MemberServiceIntegrationTest {
@Autowired MemberService memberService;
@Autowired MemberRepository memberRepository;
@Test
public void 회원가입() throws Exception {
//Given
Member member = new Member();
member.setName("hello");
//When
Long saveId = memberService.join(member);
//Then
Member findMember = memberRepository.findById(saveId).get();
assertEquals(member.getName(), findMember.getName());
}
@Test
public void 중복_회원_예외() throws Exception {
//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("이미 존재하는 회원입니다.");
}
}
복습
: MemberServiceTest에서는 main에서 쓰는 객체와 같은 객체를 써야 하므로 테스트 시작 전(@BeforeEach) DI를 써서 그 저장소를 같이 쓰게했다. 그리고 테스트에서 실행한 내용들을 지우기 위해 테스트가 끝난 후 (@AfterEach) 메소드(clearStore)를 호출하여 테스트에서 실행한 내역을 삭제했다.
MemberServiceIntegrationTest에서는 스프링 컨테이너를 가져오고 DB와 연동까지 해서 테스트를 진행할 것이기 때문에 DI과정이 필요가 없다.
@SpringBootTest
: 스프링 컨테이너와 테스트를 함께 실행한다@Transaction
: 테스트 시작 전에 트랜젝션을 시작하고 테스트 완료 후에 항상 롤백한다.
이렇게 하면 DB에 데이터가 남지 않는다.
@Transaction
에 대해서 더 설명하자면
테스트를 실행할 때 트렌젝션을 먼저 실행하고 DB에 데이터를 넣고(insert query..) 테스트 작업이 끝나면 알아서 롤백(했던거 초기화)해주는 기능을 한다. 물론 서비스에 붙으면 정상적으로 작동하고 테스트 케이스에 붙었을 때에만 이러한 기능을 수행한다. (여기서 말하는 정상적은 트렌젝션을 생성까지만 한다는 얘기같다)
그럼 스프링 없이하는 순수한 테스트는 필요없지 않나요?
매우 필요하다. 시간차이가 말도안된다.