스프링에서 테스트 코드 작성 중 엔티티의 영속화를 유지할 필요가 있다면
@Transactional이 아닌
TransactionTemplate를 사용해볼 수 있다.
테스트 코드에서 @Transactional은 테스트 시작시 열리고 테스트가 끝나면 롤백된다.
@AfterEach
@Transactional
void delete() {
Member member = memberRepository.findBySocialId(SocialType.KAKAO, "2gjdkl12333").get();
log.info("해당 id 삭제 ={}", member.getId());
memberRepository.deleteMember(member);
}
위 코드가 실행되면 member는 비영속화상태이기에 실패한다.
Removing a detached instance zypt.zyptapiserver.domain.Member#d05f0a52
트랜잭션 템플릿 사용
@AfterEach
void delete() {
transactionTemplate.execute(status -> {
Member member = memberRepository.findBySocialId(SocialType.KAKAO, "2gjdkl12333").get();
log.info("해당 id 삭제 ={}", member.getId());
log.info("영속화 ? = {}", em.contains(member));
memberRepository.deleteMember(member);
return 1;
});
}
성공적으로 영속화가 유지된다.
또는
클래스 단에 @Transactional을 붙이면 해결된다.
이게 신기한게 @AfterEach 나 @BeforeEach에 @Transactional을 붙이면 영속화가안되고
다른 테스트 메서드에는 영속화가 된다.
트랜잭션 대상이 아니여서 일지도 모른다.
검색해봐도 정보가 없고 GPT를 써서 알아본 결과
Spring Test의 트랜잭션 관리는 오직 @Test 메서드 (또는 클래스 단에 붙은 @Transactional)만을 감싸고, @BeforeEach/@AfterEach는 그 안에 포함되지 않습니다
@AfterEach에 단순히 @Transactional을 붙여도
- JUnit이 Spring의 AOP 프록시를 통해 호출해 주는 게 아니므로(=테스트 트랜잭션 관리 대상이 아님),
- 실제로는 별도 트랜잭션도, 같은 영속성 컨텍스트도 열리지 않습니다.
라고 한다.
그리고 Auditing을 테스트에서도 쓰려면 테스트의 application 애노테이션이 붙은 곳에
@EnabaleJpaAuditing을 붙여주자
@EnableJpaAuditing
@SpringBootApplication
public class ZyptApiServerApplication {}
'Back-End > Spring' 카테고리의 다른 글
프로젝트 중 잘못된 테스트 바로잡기 (2) | 2025.07.08 |
---|---|
detached entity passed to persist (0) | 2025.06.30 |
OIDC로 소셜 로그인 구현 [Spring Boot] (2) | 2025.06.14 |
filter 코드 리팩토링 해보기 (0) | 2025.04.07 |
JWT(Json Web Token) (3) | 2025.03.15 |