해결된 질문
24.05.28 23:28 작성
·
126
0
jpaRepository에서 update 관련 메서드를 테스트하던 중 고민이 생겼습니다.
update로 변경한 결과가 DB가 아닌, 영속성 컨텍스트에만 반영이 되어서 수정된 값을 확인하기 위해 find()메서드로 저장된 객체를 불러오면 수정한 것과 다른 원본 결과가 출력됩니다.
이 문제를 해결하기 위해 두 가지 방법을 생각해보았습니다.
하나는 @Modifying 애노테이션에 clearAutomatically = true 라는 옵션을 달아주는 방법이었는데, 이 방식은 테스트를 위해 프로덕션 코드를 수정하기도 하고 성능에 문제가 발생해서 제외하였고
다른 하나는 테스트 코드에 EntityManager를 이용해 강제로 flush()와 clear()를 이용해 영속성 컨텍스트를 비워주도록 하는 방법이었습니다.
이 방식도 테스트 코드가 깔끔하지 않고 더 jpa에 종속적이게 되는 것 같아서 마음에 들진 않는데 강사님은 어떤 방식으로 해결하셨는지 궁금합니다!
답변 2
0
2024. 06. 01. 15:19
안녕하세요, 김규현 님!
좋은 질문이네요 ㅎㅎ 바로 답변드리자면, 비슷한 상황에서는 저도 후자로 말씀주신 방법을 사용할 것 같습니다.
테스트 코드를 위해 프로덕션 코드를 수정하는 것은 지양되어야 할 방식이기에 @Modifying
을 사용하는 것보다는, EntityManager를 통한 컨텍스트 제어 방법이 더 좋다고 생각합니다.
다만, 말씀주신 것처럼 'JPA에 종속적인 테스트'에 대해서는 조금 더 생각을 해보아야 하는데요.
애초에 제가 소개드린 Repository 테스트 방식이 JPA에 종속적인 Spring 통합 테스트(@SpringBootTest)여서, Repository 자체는 인터페이스로 순수 스펙만 명시되어 있다고 하더라도, 테스트 방식 자체가 JPA 종속성을 염두에 둘 수밖에 없는 방식이기 때문에 필요에 따라 EntityManager를 사용하는 것은 어쩔 수 없을 것 같습니다. 오히려 자연스럽다고 볼 수도 있고요. 결국은 테스트 환경을 실행했을 때 update 행위를 수행하는 구현체가 JPA(hibernate)를 기반으로 하기 때문이죠.
도움이 되셨기를 바랍니다.
감사합니다 🙂
0
안녕하세요, 인프런 AI 인턴입니다.
jpaRepository에서 update 메서드를 테스트하는 상황에 대한 해결 방안으로 귀하께서 고려하신 두 가지 방법에 대해 말씀드린 것과 관련하여, Spring Data JPA 문서에서는 @Modifying
애노테이션 사용과 관련된 내용을 제공하고 있습니다. @Modifying
애노테이션에 clearAutomatically = true
옵션을 추가하는 것은 엔티티 매니저의 변경 내용을 clear 하여 영속성 컨텍스트와 데이터베이스 사이의 동기화 문제를 해결할 수 있는 방법 중 하나입니다.
해당 방법은 테스트 환경에서 변경된 내용을 정확하게 반영하기 위해 유용할 수 있으며, 문서에서는 다음과 같은 예시를 제공하고 있습니다.
@Modifying
@Query("update User u set u.firstname = ?1 where u.lastname = ?2")
int setFixedFirstnameFor(String firstname, String lastname);
이와 별개로, 테스트 코드에서 EntityManager를 사용하여 flush()
와 clear()
를 호출하는 방식은 영속성 컨텍스트를 수동으로 관리해야 하는 상황에서 사용될 수 있습니다. 이 방법은 테스트 환경을 더 잘 제어할 수 있게 해주지만, 코드의 복잡성을 증가시키는 단점이 있습니다.
두 방법 모두 상황에 따라 장단점이 있으므로, 프로젝트의 특정 요구 사항과 테스트 환경을 고려하여 적절한 방법을 선택하는 것이 중요합니다. 기능적 요구사항과 성능상의 고려사항을 모두 충족시킬 수 있는 최적의 방법을 찾는 것이 바람직합니다.
참고하실 수 있도록 관련 문서의 URL을 공유드리겠습니다.
- @Modifying 관련 문서: 참고 자료
여기에서 제공하는 정보가 도움이 되었기를 바랍니다. 추가 질문이 있으시면 언제든지 문의해주세요.