6.3.1 스프링 통합 테스트 코드 작성
앞서 섹션 3.5에서 진행한 회원 서비스 테스트의 경우,
스프링과는 관련 없이, 순수한 자바 코드만을 테스트하였다.
하지만 섹션 6.2에서 JDBC repository 로 DB까지 연결하는 코드를 테스트 하기 위해서는,
스프링 컨테이너와 DB를 연결한 통합 테스트를 진행해야 한다.
( Database Connection 정보들을 스프링 부트가 가지고 있기 때문)
먼저, test > java > hello.hellospring > service 폴더에
MemberServiceIntegrationTest 파일을 만들고 다음과 같이 코드 작성한다.
아래의 코드는 상단 일부만을 나타내었다.
@SpringBootTest
@Transactional
class MemberServiceIntegrationTest {
@Autowired MemberService memberService;
@Autowired
MemberRepository memberRepository;
@SpringBootTest
: 스프링 컨테이너와 테스트를 함께 실행하도록 하는 어노테이션
@Transactional
: test 를 진행하기 전에, transaction 을 한다.
: test 가 완료된 후, 롤백한다.
(아래 6.3.3에 추가 설명)
@Autowired
: test 에서는 injection 을 사용하지 않고, 단순히 Autowired 어노테이션을 주로 사용한다.
MemberRepository
: MemberServiceTest 에서는 MemoryMemberRepository 를 사용하였지만, MemberRepository 로 바꿔준다.
아래의 코드는 회원가입, 중복 회원 예약 test 코드이다.
MemberServiceTest 코드와 동일하게 작성한다.
@Test
void 회원가입(){
// given
Member member = new Member();
member.setName("spring");
// 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("spring");
Member member2 = new Member();
member2.setName("spring");
// when
memberService.join(member1);
assertThrows(IllegalStateException.class, () -> memberService.join(member2));
// then
}
전체 코드는 다음과 같다.
package hello.hellospring.service;
import hello.hellospring.domain.Member;
import hello.hellospring.repository.MemberRepository;
import hello.hellospring.repository.MemoryMemberRepository;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.transaction.annotation.Transactional;
import static org.junit.jupiter.api.Assertions.assertThrows;
@SpringBootTest
@Transactional
class MemberServiceIntegrationTest {
@Autowired MemberService memberService;
@Autowired
MemberRepository memberRepository;
@Test
void 회원가입(){
// given
Member member = new Member();
member.setName("spring");
// 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("spring");
Member member2 = new Member();
member2.setName("spring");
// when
memberService.join(member1);
assertThrows(IllegalStateException.class, () -> memberService.join(member2));
// then
}
}
6.3.2 스프링 통합 테스트
코드 작성을 완료하고 회원가입 테스트 코드를 실행하면 오류가 발생한다.
이는 db 에 이미 'spring' 이라는 이름의 회원이 존재하는데,
회원 가입 테스트 코드에서 'spring' 이라는 동일한 이름의 회원을 저장하여 발생하는 오류이다.
(실제로 오류 메시지를 확인하면, '존재하는 회원' 이라는 문구를 확인할 수 있다.)
따라서, 먼저 DB 의 데이터를 모두 삭제 해야 한다.
H2 콘솔에서 아래와 같이 delete from member; 를 작성하여 데이터를 삭제한다.
+ 참고 )
실제 test 에서는 운영하고 있는 데이터를 삭제하는 것이 아니라, 테스트 전용 db를 따로 구축한다.
다시 회원가입 test 를 돌려보면,
아래와 같이 정상적으로 작동하는 것을 볼 수 있다.
실제로 Spring 도 같이 뜨는 것도 확인할 수 있다.
6.3.3 @Transactoinal 추가 설명
앞서 6.3.2 에서 test 가 정상적으로 작동하고,
DB 에도 데이터가 정상적으로 들어가는 것을 확인할 수 있었다.
하지만, 회원가입 test 코드를 다시 한번 돌려보면, 오류가 발생하는 것을 확인할 수 있다.
즉, test 를 반복할 수 없는 문제가 발생하게 된다.
이를 위해 delete 메소드를 작성해도 되지만,
스프링에서는 Transactional 어노테이션을 지원한다.
@Transactional
data 는 커밋을 통해 DB에 반영이 되는데,
test 가 끝난 다음, 롤백 하도록 하여 DB 에 데이터가 반영되지 않도록 한다.
즉 별도의 코드를 작성하지 않아도, 테스트를 반복해서 수행할 수 있다.
Transactional 어노테이션을 사용하면,
DB 에 데이터가 반영되지 않으므로, 다음 test 에 영향을 주지 않는다.
+ 참고 )
@Transactional 은 test 에 사용했을 때만, 롤백하도록 동작한다.
(예를 들어 service 에 사용될 때에는 정상적으로 작동한다.)
실제로 test 를 여러번 반복해서 수행해도 오류가 발생하지 않는 것을 확인할 수 있다.
+ 참고 )
실제로는 앞서 실행한 통합 테스트보다,
순수한 자바 코드로 테스트 하는 '단위 테스트'를 하는 것이 더 바람직하다.
김영한 '스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술' 강의를 기반으로 작성하였습니다.
'SPRING 입문 [ 코드로 배우는 스프링 부트 ]' 카테고리의 다른 글
[스프링 입문] 섹션 6.5 스프링 DB 접근 기술 (JPA) (1) | 2023.01.18 |
---|---|
[스프링 입문] 섹션 6.4 스프링 DB 접근 기술 (스프링 통합 Jdbc Template) (0) | 2023.01.17 |
[스프링 입문] 섹션 6.2 스프링 DB 접근 기술 (순수 JDBC) (0) | 2023.01.17 |
[스프링 입문] 섹션 6.1 스프링 DB 접근 기술 (H2 데이터베이스 설치) (0) | 2023.01.17 |
[스프링 입문] 섹션 5.3 웹 MVC 개발 (회원 웹 기능 - 조회) (0) | 2023.01.10 |