스프링 입문 - 스프링 통합 테스트
이전시간에 만들었던 JdbcMemberRepository는 DB까지 연결이 된다.
그러면, 테스트도 스프링까지 다 올리고 DB까지 연결해서 동작하는 통합 테스트를 해보아야 한다.
스프링 통합 테스트를 해보자.
이전에 했던, 이런 테스트 들을 보면,
전혀 스프링과 관련이 없는 테스트들이다.
순수한 Java코드를 가지고 테스트 한 것이다.
그런데, 지금은 순수한 Java코드만 가지고 테스트 할 수 없다.
왜냐하면, 데이터베이스 커넥션 정보도 스프링 부트가 들고있고 그러기 때문이다.
그래서 지금부터는, 테스트를 스프링과 엮여서 해볼 것이다.
우선, 기존에 만들어 두었던, MemberServiceTest를 살펴보자.
이 테스트는 메모리에 저장하는 테스트이기 때문에 Java뜨는 시간만 제외하면 거의 시간소요가 없다.
이것은 JVM안에서 끝나는 테스트이다.
이번에는 DB까지 연결해서 테스트를 만들어보자.
우선은, MemberServiceTest를 복사 붙여넣기해서 이름이 MemberServiceIntegrationTest라는 클래스를 생성했다.
스프링 컨테이너와 테스트를 함께 실행하도록 하기위해 @SpringBootTest 를 붙여주고,
테스트 시작 전에 트랜잭션을 시작하고, 테스트 완료 후에 항상 롤백 하도록하여 DB에 데이터를 남기지 않게 해서 다음 테스트에 영향을 주지 않게 하기위해 @Transactional를 붙이면 된다.
그리고 이 부분을 보면, 직접 객체를 생성해서 넣어주었는데,
이제는 스프링 컨테이너에게 "MemberService, MemberRepository를 내놔!!"라고 해야한다.
파란색으로 표시된 부분은 지워주자.
테스트는, 제일 끝 단에 있는 것이기 때문에, 테스트코드를 만들 때는, 제일 편한방법으로 쓰면 된다.
@Autowired를 바로 넣어줘도 된다.
테스트를 다른데서 가져다 쓸 것이 아니기 떄문에, 그냥 테스트는 내가 필요한 것을 인젝션해서 사용하고 끝이기 때문에,
테스트케이스를 작성할 때는 필드 기반으로 @Autowired를 받는 것이 편하다.
그리고, 중요한게 있는데,
이 부분을 MemoryMemberRepository로 해주는 것이 아니라, MemberRepository로 바꿔야 한다.
@AfterEach도 지워준다.
@AfterEach가 필요했던 이유는, 메모리DB에 있는 데이터를 다음테스트에 영향이 없도록 지워주기 위함이었는데,
이제 @Transactional을 사용할 것이기 때문에 필요없다.
그다음, 회원가입 로직 그대로 있고, 중복_회원_예외 로직도 그대로 납둔다.
이것은 지워주었다.
일단, 회원 가입테스트를 돌려보자.
회원가입을 하는데, "이미 존재하는 회원입니다." 라는 예외가 발생했다.
이유를 살펴보자.
우리 DB살펴보면,
spring이라는 이름의 데이터가 저장되어 있다.
그런데, 테스트를 할 때, "spring"이라는 이름으로 회원가입을 하도록했으므로
"이미 존재하는 회원입니다." 라는 예외가 발생하는 것이다.
DB의 데이터를 완전히 지워주자.
완전히 지워주었다.
"그러면 운영하는 DB의 데이터를 막 지우는거아닌가?"라는 의문이 들 수도 있는데,
실제로는 테스트전용 DB를 따로 구축해서 테스트전용 DB의 데이터를 지우기 때문에 너무 걱정하지말자.
예제라서 이렇게 한 것이다.
이상태에서
@Transactional 만 주석처리하고 다시 회원가입 테스트를 돌려보자.
기존에 MemoryMemberRepository를 테스트할 때와 다르게
테스트를 하는데 스프링이 올라왔다. 그리고 @Configuration도 다 올라왔다.
그리고 테스트가 끝나면 스프링이 내려간다.
회원가입 테스트가 정상적으로 통과되었다.
DB를 확인해보면, spring이 정상적으로 저장되었다. (ID는 DB매커니즘에 의해 알아서 부여되므로 신경 쓰지말자.)
그런데, Test는 반복할 수 있어야하는데, 이제 다시 실행하면,
이렇게 오류가 발생한다.
DB에 spring저장한게 남아있기 때문이다.
그러면 또 전에 했던 것처럼 @AfterEach, @BeforeEach 이런식으로 해줘야하는 걸까?
@Transactional 을 사용하면 해결할 수 있다.
@Transactional 은 테스트 시작 전에 트랜잭션을 시작하고, 테스트 완료 후에 항상 롤백 하도록하여 DB에 데이터를 남기지 않게 해서 다음 테스트에 영향을 주지 않게 해준다.
그런데, 지금은 @Transactionl의 역할을 보기위해, 주석처리를 하고 테스트를 돌렷기때문에 저러한 예외가 발생한 것이다.
DB에 인서트 쿼리를 날려도 커밋을 하기 전까지는 DB에 반영이 안된다.
커밋을 자동으로 하는 오토커밋 모드로 설정할 수도 있지만,
일반적으로는 DB에 인서트 쿼리를 날러도 커밋을 하지 않으면 DB에 반영이 안된다.
@Transactional을 사용하면, 테스트(DB에 인서트 쿼리 날리고)를 끝나고 커밋이 아니라 롤백을 하는 것이다.
그러면, DB에 인서트 쿼리를 날렸어도 롤백을 하면 DB에 인서트쿼리 데이터가 반영되지 않는다.
우선, 한번은 다시 DB에 저장된 데이터를 지워주자.
그리고 @Transactional 주석을 해제해주자.
돌려보자.
회원가입 테스트를 할때, 인서트 쿼리를 날려도, DB에는 반영하지 않고 롤백한 것을 확인할 수 있다.
반복해서 테스트를 할 수 있다.
이번에는 전체를 테스트해보자.
전체 테스트를 성공했다.
이렇게해서 통합테스트에 대해서 알아보았다.
※ 그러면 통합테스트말고, 순수하게 자바코드로만 하는 단위테스트는 필요없는 것 아닌가요?
가급적이면 순수한 단위테스트가 훨씬 좋은 테스트일 확률이 높다.
왜냐하면 단위단위 쪼개서 테스트를 할 수 있기때문이다.
스프링 컨테이너 없이 테스트를 할 수 있도록 하면, 좋은 테스트를 할 수 있을 확률이 높다.
'Spring' 카테고리의 다른 글
스프링 입문 - JPA (0) | 2022.05.22 |
---|---|
스프링 입문 - 스프링 JdbcTemplate (0) | 2022.05.22 |
스프링 입문 - 순수 JDBC (0) | 2022.05.20 |
스프링 입문 - H2 데이터베이스 설치 (0) | 2022.05.20 |
스프링 입문 - 회원 웹 기능 - 조회 (0) | 2022.05.20 |
댓글
이 글 공유하기
다른 글
-
스프링 입문 - JPA
스프링 입문 - JPA
2022.05.22 -
스프링 입문 - 스프링 JdbcTemplate
스프링 입문 - 스프링 JdbcTemplate
2022.05.22 -
스프링 입문 - 순수 JDBC
스프링 입문 - 순수 JDBC
2022.05.20 -
스프링 입문 - H2 데이터베이스 설치
스프링 입문 - H2 데이터베이스 설치
2022.05.20