2022. 3. 30. 12:18ㆍBackEnd(Java)/테스트
JPA에서 DB 연산(C,R,U,D)은 Transaction 단위 안에서 실행된다. 즉, 트랜잭션이 없는 연산은 실행될 수가 없다. JPA에서는 @Transactional라는 어노테이션을 제공하여 트랜잭션 기능을 제공한다. 실제 코드를 보면서 이해해 보자!
아래의 실제 테스트를 진행 중 그림 1과 같이 오류메시지가 나타났고 확인해 보니 "현재 스레드에 엔티티 매니저가 없다 그래서 persist 함수를 호출할 수가 없다"라는 에러 메시지가 뜬것을 확인할 수 있다.
앞에서 언급했듯이 JPA는 Transcation 단위 안에서 실행되므로 @Transactional 어노테이션을 입력해주면 실행이 된다!
![](https://blog.kakaocdn.net/dn/bfmn1w/btrxVke15oS/RrGD1ReSUrgdD28iEXb7Dk/img.png)
![](https://blog.kakaocdn.net/dn/d2qMej/btrxY4vk6qU/yzgGxgnsfTbEVCCNAaBIJ1/img.png)
@Transactional 어노테이션을 추가 후 실행하였다.(그림 2 참고)
![](https://blog.kakaocdn.net/dn/bidHOr/btrxVGCeeaB/cEMZIbCkxH5PhQOR4BnQT0/img.png)
![](https://blog.kakaocdn.net/dn/dmq6I7/btrxVGPNfNl/I8hGUQaKVk7KUZ3Pb74gi0/img.png)
그런데... 실행은 잘 됐는데 DB에 보니 값이 반영이 안 되었음... (뭐지...?)
로그를 확인해 보니 트랜잭션 RollBack을 하는 문구가 보였고 구글에서 찾아보니 @Transcational 어노테이션은 테스트에서 코드 실행 후 자동으로 Rollback을 한다. 그래서 실제 Commit이 되지 않아 DB에 값이 반영되지 않았던 것이다!
![](https://blog.kakaocdn.net/dn/dE37KB/btrxU0gPjC7/h8ZkUkB5j3kA5myLHtPQQk/img.png)
실제로 DB에 값을 반영하기 위해서는 테스트 함수에 @Commit 어노테이션을 사용하면 DB에 Commit이 되어 값이 반영이 된다.(그림 4 참고)
![](https://blog.kakaocdn.net/dn/tljve/btrxWCsPIpI/R1VA153knpJ2VToHNrbHC0/img.png)
아래의 그림 5를 보면 실제 DB에 값이 반영된 것을 확인할 수 있음
![](https://blog.kakaocdn.net/dn/L6TKk/btrxWLvXUtM/PMYVvamecKbgat4nrcQ8Q0/img.png)
결론
테스트 코드 돌릴 때 DB에 반영하고 싶으면 @Commit 어노테이션을 사용하라! 아니면 JPA가 자동으로 RollBack 시켜 버린다.
참고사항
참고로 @SpringBootTest는 스프링, 통합 테스트에 사용하는 어노테이션으로 Repository 안에는 EntityManager을 사용하여 대부분의 연산을 수행하게 된다. EntityManager를 사용하려면 스프링과 통합 테스트가 필요하므로 @SpringBootTest 어노테이션을 사용하였다!
실제 개발 테스트도 중요한데, 테스트 코드 짜는 거가 더 중요하다고 느껴진다.. 더 고민을 해봐야겠음..
'BackEnd(Java) > 테스트' 카테고리의 다른 글
JUnit5 Parameterized Tests (0) | 2022.07.09 |
---|---|
AssertJ을 사용해보자! (0) | 2022.07.09 |
[assertJ] isEqualTo vs isSameAs 비교 (0) | 2022.03.30 |
단위 테스트 (0) | 2022.03.30 |