• 카테고리

    질문 & 답변
  • 세부 분야

    백엔드

  • 해결 여부

    미해결

PK값으로 테스트 할 때 질문입니다.

24.03.25 23:36 작성 조회수 107

0

  • 학습 관련 질문을 남겨주세요. 어떤 부분이 고민인지, 무엇이 문제인지 상세히 작성하면 더 좋아요!

  • 먼저 유사한 질문이 있었는지 검색해 보세요.

  • 서로 예의를 지키며 존중하는 문화를 만들어가요.

     

우선, 덕분에 테스트 코드를 작성하는데 많은 도움이 됐습니다!

 

현재 토이프로젝트 진행 중에 PK 값을 Long 타입으로 두고

@GeneratedValue(strategy = GenerationType.IDENTITY) 이 전략을 사용하니,

tearDown을 해도, 전체 테스트에서는 create하고 삭제를 하니, PK인 Long이 1L인 것을 보장을 못하더라구요.

그래서 create하는 메서드의 반환을 void로 했다가 Long 타입으로 반환하는데, 이렇게 하는 것도 좋은 코드인가요..?

@DisplayName("사용자를 조회하면 사용자의 이름, 직업, 전화번호, 성별을 조회한다.")
@Test
void getUserInfo() {
    //given
    Register register = Register.builder()
            .name("name")
            .job(Jobs.STUDENT)
            .phone("010-0000-0000")
            .man(true)
            .build();
    Long id = usersService.registerUser(register);

    //when
    UserResponse userInfo = usersService.getUserInfo(id);

    // then
    assertThat(userInfo.name()).isEqualTo("name");
    assertThat(userInfo.job()).isEqualTo(Jobs.STUDENT);
    assertThat(userInfo.phone()).isEqualTo("010-0000-0000");
    assertThat(userInfo.man()).isEqualTo(true);
}
// 단건 조회
public UserResponse getUserInfo (Long id){
    Users user = usersRepository.findById(id).
            orElseThrow(IllegalArgumentException::new);

    return UserResponse.of(user);
} 

입니다!

답변 2

·

답변을 작성해보세요.

0

안녕하세요, 강민승 님!

getUserInfo()을 테스트하기 위해 먼저 만들어둔 fixture의 id가 필요하신 상황이군요.

접근하신 방법도 나쁘지 않습니다. 다만, 테스트 코드를 위해 프로덕션 코드를 변경하는 것이 마음에 걸리신다면, 다음과 같이 접근하는 방법도 있습니다.

// ...User 생성

List<User> users = userRepository.findAll();
User targetUser = users.get(0);
Long targetUserId = targetUser.getId();

//when
UserResponse userInfo = usersService.getUserInfo(targetUserId);

매 테스트가 끝나고 다른 테스트에서 생성했던 User는 모두 클렌징되었다고 가정한다면,
위 테스트를 수행하는 시점으로 UserRepository에서 모든 User를 조회한다면 하나의 User만 조회될 것입니다.
조회한 User에서 id를 꺼내어 when절에서 사용할 수 있습니다.

감사합니다. 🙂

0

인프런 AI 인턴님의 프로필

인프런 AI 인턴

2024.03.27

안녕하세요, 인프런 AI 인턴입니다.

님의 질문에 대해 답변드립니다.

테스트 코드에서 PK 값의 일관성 문제로 고민이 많으신 것 같습니다. @GeneratedValue(strategy = GenerationType.IDENTITY) 전략을 사용할 경우, ID 값은 데이터베이스에 의해 자동으로 증가되며, 테스트가 실행될 때마다 초기화되지 않습니다. 이로 인해 각 테스트 사이에 데이터 간 격리(isolation) 문제가 발생할 수 있습니다.

테스트 코드에서 사용자 생성 후 생성된 사용자의 ID를 반환하고, 이 ID를 사용하여 사용자 정보를 조회하는 로직으로 구성한 것은 아주 적합한 접근 방식입니다. 이렇게 함으로써 실제 동작 환경에서 사용자 생성과 조회가 어떻게 이루어지는지를 잘 반영할 수 있으며, 테스트 간의 데이터 격리를 유지할 수 있습니다.

데이터 격리를 위해 테스트 데이터베이스에 @DataJpaTest와 같이 스프링 부트가 제공하는 테스트 어노테이션을 활용하거나, 테스트 전용 데이터베이스를 구성하는 방법도 고려할 수 있습니다. 각 테스트 메서드 실행 후 데이터를 정리(cleanup)하는 작업은 테스트 간의 독립성을 보장하기 위해 중요합니다.

따라서, PK 값을 반환하는 방식은 올바른 접근이며, 테스트가 예상대로 동작하도록 하는데 필수적인 부분입니다. 이와 같은 방식으로 테스트를 구성하는 것이 좋은 코드라고 할 수 있습니다.

도움이 되셨길 바랍니다. 추가적인 질문이 있으시면 언제든지 문의해주세요.