JAVA/JAVA | Spring 학습기록

[TDD] @Rollback을 쓰면 원래 DB의 데이터도 사라질까?

kth990303 2021. 8. 27. 10:42
반응형

@Rollback을 쓰기에 겁나는 사람을 위해 포스팅해본다.

 

테스트 코드를 작성할 때, @Rollback이라는 기능을 쓰면 테스트 코드에서 insert한 데이터들을 다시 rollback 시켜준다는 점은 모두 알고 있을 것이다.

예시로 db가 텅 비어있었는데, test code에서 repository.save(member1); 을 한다고 해도, @Rollback 어노테이션을 붙일 경우 db가 rollback되어 텅 비는 것을 확인할 수 있기 때문이다.

 

그럼 db가 비어있지 않고 데이터가 이미 있는 경우에선 rollback을 써도 될까?

정답은 YES.

 

@Rollback은 테스트 코드에서 insert된 데이터들만 rollback시켜주지,

모든 데이터를 rollback시킨다는 의미가 아니다.

 

db와의 트랜잭션을 위해 @Transactional 어노테이션 사용. @Rollback도 사용하였다.

위 사진에서 볼 수 있듯이

@BeforeEach, @AfterEach에 별다른 코드 없이 @Rollback 기능만 붙여주었다.

 

현재 DB에는 8개의 데이터들이 들어 있다.

@Rollback을 한다고 위 데이터들까지 사라질까?

 

테스트코드 중 join코드로 테스트 해보자.

@Test
void join() {
    Member member=new Member("test", "Silver V");

    // @Rollback을 하지 않는다면 원래 db 데이터에 test계정이 추가될 것이다.
    service.join(member);
    Optional<Member> findMemberOptional = repository.findByName(member.getName());
    Member findMember = findMemberOptional.get();

    Assertions.assertThat(findMember).isEqualTo(member);
}

@Rollback(false)로 진행할 경우, test를 마친 이후에 test계정이 insert돼있을 것이다.

우리는 그것을 원치 않으며, 테스트코드가 끝난 이후엔 다시 테스트 이전으로 되돌아가길 원하는 상태이다.

join 기능이 잘 성공했음을 TDD로 확인할 수 있으며,

콘솔의 쿼리를 보니 insert into member (name, tier) values (?, ?)를 보아하니 잘 들어갔음을 확실히 확인할 수 있다.

 

@Rollback 어노테이션이 클래스 맨 위에 붙어있으니,

db에는 test계정이 존재하지 않을 것이다.

 

그런데 잠깐, 

원래 db에 있었던 8개 데이터들까지 Rollback 돼버리는 건 아닐까?

 

아주 잘 있다.

아니다.

아주 잘 존재하고 있다.

 

위의 table이 테스트를 돌리기 전, 아래의 table이 테스트를 돌린 후 결과이다.

db 데이터들이 test 전으로 잘 돌아감을 확인할 수 있다.

 

즉, @Rollback은 전체 데이터를 롤백하는 것이 아닌, 테스트동안 변경된 내용만을 롤백해주는 것임을 확인할 수 있다.

 

혹시나, 원래 db 데이터들이 사라질 것을 염려했다면

안심하고 사용하도록 하자.

 

반응형