@DataJpaTest에서 참조하는 Entity 관련 질문 있습니다
149
작성한 질문수 1
개발자 선배님들 안녕하세요. @DataJpaTest 관련해서 궁금한점이 생겨서 질문드립니다.
제가 작성한 User Entity에서 Address Entity를 FK로 참조하고 있습니다.
여기서 UserRepository의 테스트 코드를 작성할 때
AddressRepository도 @Autowired로 등록 후 Address를 먼저 save()로 insert 후에 User Insert 테스트를 작성해야 하나요???
이러면 UserRepository의 테스트가 아니라 UserRepository, AddressRepository 두개의 테스트를 작성하는 것이라 좀 이상하다고 생각이 드네요..
제가 작성한 코드입니다.
package com.kh.bookfinder.repository;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import com.kh.bookfinder.entity.Address;
import com.kh.bookfinder.entity.User;
import com.kh.bookfinder.entity.UserStatus;
import jakarta.persistence.EntityManager;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase.Replace;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.TestPropertySource;
@ActiveProfiles("test")
@DataJpaTest
@TestPropertySource(locations = "classpath:application-test.properties")
@AutoConfigureTestDatabase(replace = Replace.NONE)
public class UserRepositoryTest {
@Autowired
UserRepository userRepository;
@Autowired
AddressRepository addressRepository;
Address givenAddress;
@BeforeEach
public void setup() {
givenAddress = Address.builder()
.si("서울특별시")
.gu("강남구")
.dong("역삼동")
.roadFullAddress("역삼역")
.build();
addressRepository.save(givenAddress);
}
@Test
public void userInsertTest1() {
// Given: User가 주어진다.
User givenUser = User.builder()
.email("user@mail.kr")
.password("password")
.phone("010-1234-5678")
.nickname("nickname")
.status(UserStatus.ADMIN)
.address(givenAddress)
.build();
// When: save() 메서드를 호출하여 User를 저장한다.
User actual = this.userRepository.save(givenUser);
// Then: actual은 givenUser와 같다.
assertThat(actual).isNotNull();
assertThat(actual).isEqualTo(givenUser);
}
@Test
@DisplayName("email은 unique로 중복이 불가능하다")
public void userInsertTest2() {
// Given: email이 같은 User가 2개 주어진다.
User givenUser1 = User.builder()
.email("user@mail.kr")
.password("password")
.phone("010-1234-5678")
.nickname("nickname")
.status(UserStatus.ADMIN)
.address(givenAddress)
.build();
User givenUser2 = User.builder()
.email("user@mail.kr")
.password("password2")
.phone("010-5678-1234")
.nickname("nickname2")
.status(UserStatus.ADMIN)
.address(givenAddress)
.build();
// When: save() 메서드를 호출하여 givenUser1를 저장한다.
User actual = this.userRepository.save(givenUser1);
// And: save() 메서드를 호출하여 givenUser2를 저장한다.
// Then: Exception이 발생한다.
assertThatThrownBy(() -> this.userRepository.save(givenUser2))
.isInstanceOf(DataIntegrityViolationException.class)
.hasMessageContaining("Duplicate");
}
@Test
@DisplayName("nickname은 unique로 중복이 불가능하다")
public void userInsertTest3() {
// Given: email이 같은 User가 2개 주어진다.
User givenUser1 = User.builder()
.email("user@mail.kr")
.password("password")
.phone("010-1234-5678")
.nickname("nickname")
.status(UserStatus.ADMIN)
.address(givenAddress)
.build();
User givenUser2 = User.builder()
.email("user2@mail.kr")
.password("password2")
.phone("010-5678-1234")
.nickname("nickname")
.status(UserStatus.ADMIN)
.address(givenAddress)
.build();
// When: save() 메서드를 호출하여 givenUser1를 저장한다.
User actual = this.userRepository.save(givenUser1);
// And: save() 메서드를 호출하여 givenUser2를 저장한다.
// Then: Exception이 발생한다.
assertThatThrownBy(() -> this.userRepository.save(givenUser2))
.isInstanceOf(DataIntegrityViolationException.class)
.hasMessageContaining("Duplicate");
}
}
읽어주셔서 감사합니다..!
답변 1
0
안녕하세요, 인프런 AI 인턴입니다.
이진호님의 질문에 답변드리겠습니다. @DataJpaTest는 주로 JPA 관련 설정만 로드하여 레포지토리 레이어의 컴포넌트에 대한 테스트를 집중적으로 수행할 때 사용됩니다. 따라서 UserRepository의 테스트 코드를 작성할 때 필요한 Address 엔티티를 먼저 저장하는 것이 올바른 접근입니다. 이는 AddressRepository와 UserRepository를 동시에 테스트하는 것이 아니라, UserRepository 테스트에 필요한 사전 조건을 충족시키기 위한 준비 과정으로 볼 수 있습니다. 실제 애플리케이션에서도 사용자를 저장하기 전에 주소 정보가 미리 존재해야 하는 경우가 많으므로, 이러한 테스트 설정은 실제 사용 사례를 잘 반영하고 있습니다.
또한, @DataJpaTest는 기본적으로 내장된 인메모리 데이터베이스를 사용하여 테스트를 실행하지만, @AutoConfigureTestDatabase(replace = Replace.NONE) 어노테이션을 사용하여 실제 데이터베이스에 대한 테스트를 진행할 수도 있습니다. 이 경우 실제 DB 환경을 그대로 사용하여 데이터가 잘 삽입되고 관계가 올바르게 매핑되는지 확인할 수 있습니다.
따라서, 이진호님이 작성하신 테스트 코드는 굉장히 타당하며 User 엔티티와 연관된 Address 엔티티를 먼저 저장하는 접근 방식은 적절합니다.
읽어주셔서 감사합니다.
섹션2, 대화&세션관리 수업 자료 누락
0
8
1
영상 다운로드는 안되나요?
0
11
0
IntelliJ IDEA 체험 만료
0
12
1
부하 테스트 시 설정 관련 질문드립니다
1
27
1
HelloSpringApplication.java 클래스 실행 오류
0
12
1
build 시 에러 해결방법 공유(docker.desktop 업데이트 -> 의존성 버전 수정)
0
30
2
예외처리 3강 문의
0
29
1
챌린지 시작일 문의
0
39
0
Inner class로 Config를 지정하는 이유
0
29
1
26년2회 실기기출은 언제쯤...
0
59
2
네이버 API | '검색 - 책' API 제공 중단
0
42
2
ArticleReadService 관련 질문
0
30
1
kafka 이벤트 발행 실패 시 at-least-once를 보장하는 방법이 궁금합니다.
1
71
1
이론 공부법 요약본 버전 업데이트 문의
0
39
2
domain에 @Entity 와 Repository를 함께 둔 이유가 궁금합니다
1
52
1
해당 프로젝트를 똑같이 따라하려니 spring installer가 버전이 17부터 가능하네요.
0
26
1
Part 2 듣기전 복습하던 중, 아키텍처에 관한 질문이 있습니다.
0
47
2
테스트는 인터페이스를 대상으로 만드는것에 대해 궁금한 점이 있습니다.
0
32
1
Jib 이미지 빌드에서 docker credential 관련으로 이슈가 있다면
1
81
1
리뉴얼 시기
0
52
2
스크립트에 대해 질문 있습니다.
1
60
1
같은 사용자가 연속된 중복 호출할 경우 어떻게 되는지 궁금합니다!
2
74
1
조건 검색 질문
0
40
1
JPA 엔티티로 만들었다고 기술종속이 아닌지에 대한 질문
0
55
3





