작성
·
96
·
수정됨
0
멤버를 저장하는 테스트에서 EntityManager#flush()를 호출해서 플러시되어 DB까지 쿼리문이 제대로 가는지 검증하시는 것을 보았습니다. (저는 플러시까지 테스트해볼 생각을 못했어서 아주 인상깊었습니다 ㅎㅎ)
하지만 해당 부분이 검증문 없이 홀로 호출되고 있습니다.
좀더 의도를 드러내기 위해서는 assertThatCode(() -> em.flush()).doesNotThrowAnyException()
처럼 코드를 작성하는게 더 좋지 않을까 싶어서 질문드립니다!
@Test
void 멤버를_저장한다() {
var member = MemberFixture.createAny();
memberRepository.save(member);
assertThat(member.id()).isNotNull();
assertThatCode(() -> em.flush())
.doesNotThrowAnyException();
}
답변 2
0
createMember() 테스트에서 flush()는 그 기능을 검증하기 위해서 넣은 것이 아닙니다. JPA 테스트가 처음 나오는 부분이라 제가 flush를 할 때 SQL이 어떤 게 날라가는지 눈으로도 볼 수 있다는 설명을 드린 것 뿐이고요. flush()에 의해서 SQL이 실행되는지를 검증하려는 목적이 아닙니다.
강의에서 말씀드렸을텐데 테스트가 하나의 트랜잭션으로 묶이는 경우에 flush()를 하지 않으면 DB까지 SQL이 날라가지도 않은채로 테스트가 끝날 수 있고요. findById()를 해봤자 캐시에서 읽어오기 때문에 런타임에 실제 DB와 상호작용했을 때 문제가 없다는 것을 검증할 수 없기 때문에 넣은 것입니다. clear()는 캐시를 지우기 위한 것이고요.
flush(), clear()는 검증할 대상이 아니라, 이후 이어지는 테스트의 검증 기능이 제대로 작동하게 하기 위한 보조 작업일 뿐입니다.
0
안녕하세요, 인프런 AI 인턴입니다.
Dompoo님이 언급하신 EntityManager의 flush()
메서드에 대한 검증은 멀티 스레드 환경에서 데이터 일관성을 확인하는 데 중요한 역할을 합니다. flush()
호출 시점에서 실제로 데이터베이스에 반영되는 쿼리를 통해 DB와의 동기화를 강제하기 때문입니다.
말씀하신 대로 assertThatCode(() -> em.flush()).doesNotThrowAnyException()
를 추가함으로써, flush()
동작이 정상적으로 수행되고 예외 없이 처리되는지 확인할 수 있습니다. 이는 코드의 의도를 명확히 드러내며, 특정한 상황에서 발생할 수 있는 예외를 사전에 체크하는 데 도움을 줄 수 있습니다.
이러한 검증이 추가되면, 해당 메서드 호출로 인해 예상하지 못한 예외가 발생하는 경우를 미리 탐지할 수 있습니다. 특히, 개발시 트랜잭션 경계나 영속성 컨텍스트 관련해서 발생할 수 있는 문제를 빠르게 인지하고 대응할 수 있게 해줍니다.
이와 관련된 좋은 사례로, 테스트에서의 @Transactional 사용에 대해 질문이 있습니다. 이 게시물을 참고하시면 실질적인 적용 예와 함께 트랜잭션 처리가 테스트에서 어떻게 활용되는지를 이해하는 데 도움을 받을 수 있습니다.
제가 제공한 설명이 Dompoo님께 도움이 되었길 바랍니다. 추가적인 질문이나 더 깊은 주제가 필요하시다면 언제든지 말씀해 주세요!
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.
라는 부분에서 flush도 테스트 대상이라고 생각한 것 같습니다. 단지 눈으로 확인하기 위함이라면 필요없을 것 같네요! 감사합니다!!