인프런 커뮤니티 질문&답변

constela10님의 프로필 이미지

작성한 질문수

실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발

MemberServiceTest

작성

·

92

0

실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발 섹션 4 회원 기능 테스트 강의 질문입니다.

 

@RunWith(SpringRunner.class)
@SpringBootTest
@Transactional
class MemberServiceTest {

    @Autowired MemberService memberService;
    @Autowired MemberRepository memberRepository;

    @Test
    public void 회원가입() throws  Exception {
        // given
        Member member = new Member();
        member.setName("kim");

        // when
        Long saveId = memberService.join(member);

        // then
        assertEquals(member, memberRepository.findOne(saveId));
    }

    @Test
    public void 중복_회원_예외() throws Exception {
        // given
        Member member1 = new Member();
        member1.setName("kim");

        Member member2 = new Member();
        member2.setName("kim");

        // when & then
        assertThrows(IllegalStateException.class, () -> {
            memberService.join(member1);
            memberService.join(member2);
        });
    }
}

Junit5를 사용했다는 점을 제외하고는 강의와 똑같이 코드를 작성했습니다.

이때 회원가입관련 테스트에서 강의에서는 insert문이 나가지 않지만 저는 따로 Rollback을 false로 설정하지 않아도 insert문이 실행되더군요. 이유가 궁금합니다.

사진에서 확인할 수 있듯이 Rollback이 되었기 때문에 트랜잭션이 커밋되지 않아 insert 쿼리가 발생하면 안될 것 같은데 왜 실행되는지 이유를 모르겠습니다.

 

답변 2

0

안녕하세요. constela10님, 공식 서포터즈 코즈위버입니다.

쿼리 내용으로 보아 중복회원가입 시 insert 쿼리가 발생하는 것으로 보입니다.

중복회원 검증시 findByName("사용자이름") 과 같이 키가 아닌 값으로 데이터를 조회하는 부분이 있을 수 있습니다. 이 경우 JPA는 조회쿼리를 수행하기전에 데이터베이스와 동기화(persist) 작업을 수행하며 이 때 inser 쿼리가 발생합니다.

JPA에서 JPQL을 수행하기전에 강제로 데이터베이스 동기화가 발생하는 것과 마찬가지라고 생각해주세요.

감사합니다.

0

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

constela10님께서 질문하신 내용은 JUnit5를 사용하여 SpringBootTest@Transactional 어노테이션을 활용한 테스트 중, @Transactional로 인해 롤백이 예상되지만 실제로 INSERT 문이 실행되는 이유와 관련이 있습니다.

Spring Boot와 JPA를 사용한 개발에서 JUnit 테스트를 실행할 때 @Transactional 어노테이션은 테스트가 끝난 후 데이터를 초기 상태로 롤백하여 DB에 영구적인 변경을 남기지 않도록 돕습니다. 그러나 실제로 SQL 로그를 통해 INSERT 문이 실행되는 것을 확인할 수 있습니다. 이는 스프링 테스트 컨텍스트가 @Transactional 어노테이션이 붙어 있을 경우 테스트 실행 도중에는 실제 DB에 데이터를 추가하지만, 테스트 완료 시에 이를 롤백하기 때문입니다. 즉, 테스트 실행 중 데이터 접근 로직을 검증하기 위해 실제 SQL이 실행되지만, 테스트가 종료될 때 모든 데이터 변경 사항은 롤백되어 반영되지 않는 것입니다.

constela10님의 경우도 이러한 상황에 해당됩니다. 로그에서 INSERT 문이 실행된 것으로 보이지만, 마지막에 Rollback이 되어 실제 데이터베이스에는 이 변경 사항들이 반영되지 않은 상태입니다.

섹션 4 - 회원 기능 테스트 강의에서 중복_회원_예외()메서드를 실행할 때 INSERT 쿼리가 실행되는 이유 질문에서도 비슷한 상황에 대한 논의가 있었습니다. 이는 Spring Framework에서 제공하는 @Transactional 어노테이션의 동작 방식을 이해하는 데 도움이 될 수 있습니다.

이 과정에서 실험적으로 데이터를 다루고 싶을 때, 데이터의 영구적 변경을 원하지 않는 경우 @Transactional 어노테이션을 활용하는 것이 좋습니다. 실험적인 변경을 DB에 반영해 본 후 자동으로 롤백하는 기능으로, 테스트 케이스 작성 시 매우 유용하게 사용됩니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.