Back-End/Spring

테스트에서 영속화

Meluu_ 2025. 6. 30. 20:07

 

스프링에서 테스트 코드 작성 중 엔티티의 영속화를 유지할 필요가 있다면

@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 {}