프로그래밍/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 {}