본문 바로가기
Programming Language/JPA

[JPA] 테스트 코드 실행 후 데이터 rollback 설정하기

by happy coding! 2022. 8. 15.
반응형

상황

  • CRUD (데이터 저장/조회/수정/삭제) 로직을 구현한 후 JUnit을 이용하여 테스트 코드를 작성하는 경우
@Entity
@Getter @Setter
public class Member {

    @Id @GeneratedValue
    private Long id;
    private String username;
}
@Repository
public class MemberRepository {

    @PersistenceContext
    private EntityManager em;

    public Long save(Member member) {
        em.persist(member);
        return member.getId();
    }

    public Member find(Long id) {
        return em.find(Member.class, id);
    }
}
  • 위와 같이 Member 객체를 만들고 MemberRepository에서 save와 find를 구현하였다.
  • 그리고 테스트를 위해 MemberRepositoryTest를 구현한다.
@RunWith(SpringRunner.class)
@SpringBootTest
public class MemberRepositoryTest {

    @Autowired MemberRepository memberRepository;

    @Test
    public void testMember() throws Exception {
        // given
        Member member = new Member();
        member.setUsername("아이유");

        // when
        Long savedId = memberRepository.save(member);
        Member findMember = memberRepository.find(savedId);

        // then
        Assertions.assertThat(findMember.getId()).isEqualTo(member.getId());
        Assertions.assertThat(findMember.getUsername()).isEqualTo(member.getUsername());
    }
}
  • 테스트를 위해 DB에 데이터를 저장하는 memberRepository.save(member)를 호출하한다.
  • 테스트 완료 후, 해당 데이터는 rollback 되어야 한다.

@Transactional 어노테이션 추가

@RunWith(SpringRunner.class)
@SpringBootTest
public class MemberRepositoryTest {

    @Autowired MemberRepository memberRepository;

    @Test
    @Transactional
    public void testMember() throws Exception {
        // given
        Member member = new Member();
        member.setUsername("아이유");

        // when
        Long savedId = memberRepository.save(member);
        Member findMember = memberRepository.find(savedId);

        // then
        Assertions.assertThat(findMember.getId()).isEqualTo(member.getId());
        Assertions.assertThat(findMember.getUsername()).isEqualTo(member.getUsername());
    }
}
  • DB에서 결과를 확인해보면, Test 코드로 실행되어 저장된 데이터는 존재하지 않는다.
  • 테스트 완료 직후 rollback 되어, 실제로는 저장되지 않는다.
  • @Transactional은 테스트 케이스 (@Test)에 선언 시 테스트 시작 전에 트랜잭션을 시작하고, 트랜잭션 완료 후 항상 롤백을 하여 다음 테스트에 영향을 주지 않는다.

rollback false 지정

  • 반대로 rollback이 수행되지 않도록 설정할 수도 있다.
  • Class 단위의 @Transactional 어노테이션을 선언한 경우 모든 메서드에 대해 트랜잭션이 적용된다.
  • 하지만 특정 메서드에서만 rooblack이 되지 않도록 설정하고 싶은 경우 사용할 수 있다.
@RunWith(SpringRunner.class)
@SpringBootTest
@Transactional
public class MemberRepositoryTest {

    @Autowired MemberRepository memberRepository;

    @Test
    @Rollback(false) // rooblack 되지 않도록 설정 
    public void testMember() throws Exception {
        // given
        Member member = new Member();
        member.setUsername("아이유");

        // when
        Long savedId = memberRepository.save(member);
        Member findMember = memberRepository.find(savedId);

        // then
        Assertions.assertThat(findMember.getId()).isEqualTo(member.getId());
        Assertions.assertThat(findMember.getUsername()).isEqualTo(member.getUsername());
    }
}
반응형

'Programming Language > JPA' 카테고리의 다른 글

[JPA] 영속성 컨텍스트란  (0) 2021.10.22

댓글