[JPA] @DataJpaTest에서 update문 확인 방법
Updated:
👩🏻💻 @DataJpaTest 어노테이션으로 테스트할 때 update문을 확인하는 방법을 알아봅니다.
@DataJpaTest 어노테이션을 사용해 JpaRepositoy를 테스트하는 경우, update 테스트를 실행하면 select문만 실행될 뿐 udpate은 보이지 않습니다.
@DisplayName("update 테스트")
@Test
void update_테스트() {
//given
Article article = articleRepository.findById(1L).orElseThrow();
String updatedHashtag = "#Springboot";
article.setHashtag(updatedHashtag);
//when
Article savedArticle = articleRepository.save(article);
//then
assertThat(savedArticle).hasFieldOrPropertyWithValue("hashtag", updatedHashtag);
}
Hibernate:
select
a1_0.id,
a1_0.content,
a1_0.created_at,
a1_0.created_by,
a1_0.hashtag,
a1_0.modified_at,
a1_0.modified_by,
a1_0.title
from
article a1_0
where
array_contains(?,a1_0.id)
이유는 @DataJpaTest에 기본적으로 transactional이 걸려있기 때문입니다. 즉, @DataJpaTest 어노테이션을 선언하면 모든 테스트 메서드들은 자동으로 transactional이 되고, transactional은 기본으로 rollback이 동작합니다.
따라서 테스트 안에서의 변경점이 rollback에 의해 생략될 수 있는데, 그중 하나가 update문입니다.
영속성 컨텍스트로부터 가져온 데이터를 DB에 반영하려면 save() 대신 saveAndFlush()
를 사용해 flush 처리를 하면 됩니다. 적용하면 아래처럼 update문이 실행되는 걸 확인할 수 있습니다.
flush란? 영속성 컨텍스트의 변경 내용을 DB에 반영하는 것을 말한다. Transaction commit이 일어날 때 flush가 동작하는데, 이때 쓰기 지연 저장소에 쌓아 놨던 INSERT, UPDATE, DELETE 쿼리가 DB에 전송된다.
다만 transactional에 의해 rollback될 것이므로 실제로 반영은 되지 않습니다.
@DisplayName("update 테스트")
@Test
void update_테스트() {
//given
Article article = articleRepository.findById(1L).orElseThrow();
String updatedHashtag = "#Springboot";
article.setHashtag(updatedHashtag);
//when
Article savedArticle = articleRepository.saveAndFlush(article); //saveAndFlush로 변경
//then
assertThat(savedArticle).hasFieldOrPropertyWithValue("hashtag", updatedHashtag);
}
Hibernate:
select
a1_0.id,
a1_0.content,
a1_0.created_at,
a1_0.created_by,
a1_0.hashtag,
a1_0.modified_at,
a1_0.modified_by,
a1_0.title
from
article a1_0
where
array_contains(?,a1_0.id)
Hibernate:
update
article
set
content=?,
created_at=?,
created_by=?,
hashtag=?,
modified_at=?,
modified_by=?,
title=?
where
id=?