프로그래밍/spring
테스트 코드에서의 @Transactional
승민아
2024. 9. 24. 18:07
먼저 아래의 테스트 코드를 보자.
@SpringBootTest
class ItemRepositoryTest {
@Autowired
ItemRepository itemRepository;
@Autowired
PlatformTransactionManager transactionManager;
TransactionStatus status;
@BeforeEach
void beforeEach() {
// 트랜잭션 시작
status = transactionManager.getTransaction(new DefaultTransactionDefinition());
}
@AfterEach
void afterEach() {
// 트랜잭션 롤백
transactionManager.rollback(status);
}
@Test
void test() {
...
}
}
테스트 코드에서 실행한 DB 연산들을 테스트 코드 실행 이전의 상태로 돌리고싶다면
@BeforeEach, @AfterEach를 통해서 트랜잭션의 획득과 롤백을 진행해야한다.
PlatformTransactionManager가 무엇인지는 https://non-stop.tistory.com/726 를 참고하자!
간단히 설명하자면, 다른 트랜잭션 구현체를 교체하기 쉽게 트랜잭션의 기능을 추상화한 것이다
이 과정을 @Transactional 어노테이션을 붙여줌으로써 간단히 할 수 있다.
@SpringBootTest
@Transactional
class ItemRepositoryTest {
....
}
@Transactional 어노테이션을 기존 프로젝트의 main에서 사용했을땐
로직이 성공적으로 수행되었다면 커밋을하도록 동작했다.
하지만, 테스트 코드에서의 @Transactional은 테스트가 끝나면 자동으로 롤백 시켜준다.
면접때 autocommit false와 관련해서 질문을 받았었는데 이제 이해가 됐다.
트랜잭션의 시작시 일어나는 상황은
트랜잭션 매니져를 이용해 오토커밋을 false로하고 작업 도중에 이상이 생기면 롤백을 시키는것이다.
이것을 테스트코드에서는 @Transactional을 붙여서 자동으로 롤백을 시킬 수 있는 것이다.
한번씩 테스트 코드에서 롤백을 원치않을때도 있었는데
그럴땐 아래와 같이 @Commit을 클래스나 메서드에 붙이면
테스트 종료시 롤백하지 않고 커밋을 해준다.
import org.springframework.test.annotation.Commit;
@Commit
@Transactional
@SpringBootTest
class ItemRepositoryTest {}