작성
·
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에 반영해 본 후 자동으로 롤백하는 기능으로, 테스트 케이스 작성 시 매우 유용하게 사용됩니다.
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.