• 카테고리

    질문 & 답변
  • 세부 분야

    백엔드

  • 해결 여부

    미해결

테스트에 @Transactional 뺀다고 이렇게 하면 좀 과한가요?

24.01.27 09:40 작성 24.01.27 09:55 수정 조회수 292

0

  • 당연히 구글링 해보셨져? 원하는 결과를 못찾으셨나요? 어떤 검색어를 입력했는지 알려주세

  • 문제가 발생한 코드(프로젝트)를 Github에 올리시고 링크를 알려주세요.

안녕하세요 선생님 강의 잘 보고 있습니다! 테스트 메서드에 @Transactional을 다는 것이 테스트를 오염시킬 수 있다는 말씀을 듣고 이리저리 검색해본 결과 저걸 빼고 싶어졌습니다. 덕분에 jpa와 트랜잭션에 대해 잘 몰랐는데 조금 알게됐고, TransactionTemplate을 주입해서 sessions를 초기화하고 꺼내는 코드를 짜봤습니다. 코드를 너무 과하게 키운건 아닌가 싶기도 하고, 한편 Transactional 어노테이션 붙이는거랑 결국 별 차이가 없는건가 싶기도 해서 의견을 여쭤보고 싶습니다. 건강관리 잘 하시길 바랍니다요

 


@Test
@DisplayName("로그인 성공 후 세션 생성")
void test2() throws Exception {

    Member member = memberRepository.save(Member.builder()
            .name("hi")
            .email("test@test.com")
            .password("1234")
            .build());

    Login login = Login.builder()
            .email("test@test.com")
            .password("1234")
            .build();

    mockMvc.perform(post("/auth/login")
                    .contentType(APPLICATION_JSON)
                    .content(objectMapper.writeValueAsString(login))
            )
            .andExpect(status().isOk())
            .andDo(print());

    List<Session> memberSessions = transactionTemplate.execute(status -> {
        List<Session> sessions = memberRepository.findById(member.getId())
                .orElseThrow(UserNotFound::new)
                .getSessions();
        Hibernate.initialize(sessions);
        return sessions;
    });

    Assertions.assertEquals(1L, memberSessions.size());
}

 

답변 2

·

답변을 작성해보세요.

0

안녕하세요.

테스트에서 Transactional이 꼭 나쁜건 아니지만 개인적으로는 불필요하게 넣는건 지양하고 있습니다.

그런데 위 코드는 그냥 SessionRepository를 통해서 읽어와도 될것 같은데욧!

감사합니다.

0

인프런 AI 인턴님의 프로필

인프런 AI 인턴

2024.01.29

안녕하세요, 인프런 AI 인턴입니다.

홍성진님, 테스트 코드에서 @Transactional 어노테이션 제거에 대하여 올바르게 접근하고 계십니다. Spring Boot에서 제공하는 @Transactional 어노테이션은 테스트마다 트랜잭션을 적용하여 테스트가 다른 테스트에 영향을 주지 않도록 롤백하는 용도로 사용됩니다. 테스트 케이스에 따라 이 어노테이션을 제거하고자 할 때는 몇 가지 다른 방법을 고려할 수 있습니다.

TransactionTemplate을 사용해서 커스텀 트랜잭션 관리를 하는 접근 방식은 유연성을 제공합니다. 이 방법을 통해 트랜잭션의 범위와 롤백 여부를 테스트 메서드 수준에서 보다 세밀하게 조정할 수 있습니다. 하지만 이를 사용할 때 코드 복잡성이 증가할 수 있으므로, 정말 필요한 경우에만 사용하는 것이 좋습니다.

올려주신 코드는 테스트에 대한 명확한 트랜잭선 관리와 함께 세션 정보를 초기화하고 검사하는 좋은 예제입니다. 그러나, TransactionTemplate 이 아닌 트랜잭션을 명시적으로 끄는 방법을 사용하고 싶다면 @DataJpaTest에서 @Transactional(propagation = Propagation.NOT_SUPPORTED)을 사용하여 트랜잭션을 비활성화하는 방법도 있습니다.

예를 들어 다음과 같이 사용할 수 있습니다:

@DataJpaTest
@Transactional(propagation = Propagation.NOT_SUPPORTED)
class MyRepositoryTests {

    // 이곳에 실제 테스트 코드를 작성합니다.

}

위의 어노테이션을 설정하면 테스트 메서드가 개별적으로 실행되며 트랜잭션을 사용하지 않음을 명시할 수 있습니다. 이 경우 테스트 작성 시 데이터 정리를 수동으로 관리해야 할 수 있습니다.

결론적으로, 올바른 접근 방식은 테스트의 목적과 필요한 단위의 격리 수준에 따라 결정됩니다. 간단한 경우에는 @Transactional을 그대로 사용하는 것이 좋고, 복잡한 트랜잭션 관리가 필요한 경우에는 TransactionTemplate이나 다른 방법을 사용해 트랜잭션을 컨트롤하는 것이 바람직할 수 있습니다.

참고가 되었기를 바라며, 계속해서 좋은 학습 경험을 이어가시길 바랍니다. 홍성진님의 더욱 건강에 유의하시길 바라겠습니다. 화이팅입니다!