상황
- 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());
}
}