inflearn logo
강의

講義

知識共有

トビーのクリーン・スプリング - ドメインモデルパターンとヘキサゴナルアーキテクチャ Part 1

エンティティ識別子とJPAエンティティ

테스트클래스명이 테스트 목적을 잘 나타내지 못하는 것 같습니다.

144

Dompoo

投稿した質問数 14

0

MemberRepositoryTest는 EntityManager@DataJpaTest 등 Jpa와 깊게 관련되어있는 테스트로 이해됐습니다. EntityManager#flush() 가 잘 호출되는지 확인하는 부분도 그런 이유에서 이해됩니다.

하지만 테스트명이 MemberRepositoryTest인 점에서 헷갈리는 부분이 발생합니다. MemberRepository 인터페이스의 메서드를 테스트하는 것이 목적이라면 좀 더 추상화된 테스트를 작성하는 것이 옳지 않았나? 라는 것이 주된 궁금증입니다.

 

물론 Spring Data JPA 특성상 런타임에 구현체가 만들어지기 때문에, 테스트 대상은 인터페이스를 사용해야 한다는 것은 이해합니다만, 최소한 클래스명은 좀 더 구체적으로 작성해주는 것이 의도에 부합하지 않나? 해서 질문드립니다! 어떻게 생각하시나요?

java spring spring-boot jpa 리팩토링 ddd

回答 2

2

tobyilee

스프링 데이터 JPA와 같이 코드를 자동 생성하는 기술을 사용할 때 고민이 되는 부분입니다.

테스트는 오브젝트를 실행해야 하기 때문에 구현 클래스를 사용해야 하는데 스프링 데이터는 클래스를 런타임에 자동으로 만들어주기 때문에 이걸 테스트 할 수 있는 방법은 @DataJpaTest와 같이 스프링 컨테이너를 이용해서 JPA 환경을 만들고 인터페이스 타입의 빈을 가져와 테스트하는 것 뿐이죠.

그런데 특정 클래스 구현에 대한 단위 테스트가 아니라 통합 테스트라고 본다면 리포지토리 인터페이스에 현재 매핑되는 빈(bean)을 테스트 하는 것으로는 RespositoryTest가 자연스럽다고 생각됩니다. 그 인터페이스로부터 출발해서 뒤에 (메모리) DB까지 다 검증하는 테스트 코드이기 때문이죠.

비슷하게 애플리케이션 계층의 provided 인터페이스를 타고 테스트 하는 경우에도 스프링 컨테이너를 띄우는 통합테스트인 경우엔 테스트를 수행하면서 여러 계층과 기술이 통합되어서 테스트가 됩니다. 그게 테스트 만들기도 좋고, 실제와 유사하게 기능의 동작을 검증하는 것이 자연스럽기 때문에 애플리케이션 서비스에 대한 단위 테스트보다 더 선호되는 것이죠.

사실 인터페이스만 테스트할 방법이란 없습니다. 거기에 스텁을 만들어 넣고 테스트 한다면 아무런 가치가 없을 것이니까요. 대체로 리포지토리, DAO와 같은 코드는 DB 기능을 사용하는 애플리케이션의 인터페이스(자바의 인터페이스가 아니라 DB에 대한 시스템 입장에서 인터페이스)이기 때문에 그 자체로 테스트 한다는 것도 별 가치가 없습니다. 리포지토리 구현 클래스가 있다고 하더라도, EntityManager를 목킹해서 테스트 하는 건 테스트로서 별 가치를 주지 못하기 때문에 그렇습니다.

리포지토리에 정의된 기능이 비록 스프링 데이터가 자동으로 구현을 만들어주긴 하지만, 그 구현을 이끌어내는 관례가 인터페이스에 반영되어 있기 때문에 지금 코드가 충분히 인터페이스 테스트이기도 하다는 생각인데요.

혹시 더 나은 이름을 생각하신 게 있으신가요.

1

Dompoo

먼저 빠르고 양질의 답변에 너무 감사드립니다!! 강의 정말 잘 보고 있습니다. ㅎㅎ

 

먼저 제가 이런 질문을 드렸던 배경을 설명드리고 싶습니다. 저는 원래 다음과 같이 생각했습니다.

인터페이스가 테스트 대상이라면, 구현체가 무엇이 오든 테스트도 깨지지 않아야 한다. 그것이 인터페이스의 존재 목적이기 때문에 자연스러운 테스트 흐름이다.

그래서 MemberRepositoryTest라는 이름의 테스트가 JPA에 깊게 관여되어있던 것이 부자연스럽게 느껴졌습니다.

 

저도 토비님의 의견에 전적으로 동의합니다. 인터페이스란 단위를 지키기 위해서 짜는 테스트는 실용적 가치가 매우 작을 것 같습니다. 따라서 실제 엔티티매니저와 @DataJpaTest를 통해서 짜는 통합테스트의 형태는 매우 마음에 듭니다.
따라서 인터페이스 -> 스프링 DI에 의한 구현체로 이어지는 전체 흐름을 테스트하시려는 의도셨다면 현재 테스트명이 그 목적에 가장 잘 부합하는 것 같습니다.

테스트의 목적에 대한 새로운 시선을 얻게 되는 것 같습니다. 감사합니다!

1

communityai8509

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

Dompoo님의 질문은 테스트 클래스의 이름을 통해 테스트의 목적과 의도를 명확히 표현할 필요성에 대한 고찰을 주제로 하고 있습니다. 테스트 클래스나 테스트 메서드의 이름은 코드 유지보수성과 가독성 측면에서 중요합니다. 다음은 이와 관련해 유사한 답변과 자료를 제공하고자 합니다.

테스트 클래스 및 메서드 명명 규칙의 중요성

테스트 클래스의 이름은 단순히 어떤 클래스나 메서드를 테스트하는지를 넘어서, 그 테스트의 목적과 대상의 특성을 잘 나타내야 할 필요가 있습니다. 일반적으로 다음과 같은 명명 규칙을 적용할 수 있습니다:

  1. 명확한 대상 식별: 테스트 클래스의 이름은 대상 클래스나 인터페이스의 역할을 설명해야 합니다. 예를 들어, MemberRepositoryTest는 특정 리포지토리를 테스트하는 클래스임을 명확히 표현할 수 있습니다.

  2. 테스트 의도 반영: 이름에 테스트의 특수한 목적이나 조건을 포함시킴으로써 더 많은 정보를 제공할 수 있습니다. 예를 들어, MemberRepositoryDataJpaIntegrationTest라면, 단순히 리포지토리의 인터페이스뿐 아니라 JPA 관련 통합 테스트를 실행한다는 점을 명확히 할 수 있습니다.

유사한 질문과 자료

토비님의 강의에서 다루어진 @Transactional 및 JPA와 관련된 테스트에 대한 내용은 자주 논의되곤 합니다. 테스트에서의 @Transactional 사용에 대해 질문이 있습니다.에서는 테스트 클래스와 메서드가 경계와 의미를 어떻게 명확히 할 것인지에 대해 다루고 있습니다. 이 답변에서는 JPA와 관련된 테스트 방법뿐 아니라 명명과 설계 측면까지도 넓게 다룹니다.

현재 담포님이 제기하신 테스트 클래스의 명명과 관련된 고민은 소프트웨어 개발에서 지속적으로 고려해야 할 주제입니다. 위의 자료를 참고하여 명명 규칙을 재검토하고, 보다 명확하고 유지보수하기 쉬운 테스트 코드를 설계하는 데 도움이 되길 바랍니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

도메인 모델에서 관계와 규칙을 구분하는 방법

0

33

2

헥사고날 아키텍처에서의 배치, 시큐리티, 비동기 이벤트 처리는 어떻게 하나요?

0

109

2

어댑터에서 도메인에 직접 의존하는 경우에 대해

0

112

2

Member 도메인이 PasswordEncoder를 받는 구조 질문 있습니다.

0

98

2

MemberService와 EmailSender 책임 분리에 대한 질문

0

100

2

NonNullApi를 NullMarked로 대체하라고 합니다.

0

120

2

39. 문서와 코드 다듬기 updateInfo 테스트 질문 있습니다.

0

70

2

Repository Adapter 설계에 대해 피드백을 부탁드립니다

0

102

2

헥사고날 part2 강의 출시 예정일 문의 드립니다.

0

242

2

PT 문의사항

0

95

1

초기 어플리케이션 구동 시 compose.yml 파싱 오류

0

146

2

애플리케이션의 JPA 리턴과 도메인 모델

0

124

2

애그리거트 루트의 하위 도메인들의 depth가 깊어질 때 문의

0

132

2

페이징 처리를 해야한다면 어떻게 해야할까요?

0

185

2

애그리거트의 repository

0

115

2

Domain Expert가 정확히 어떤 역할을 하는 사람인가요?

0

224

1

회원 애플리케이션 서비스 테스트 (1)

0

101

2

정적 팩토리 메서드 관련 질문드립니다!

0

102

2

spotbug + @NonNullApi 로만 Null 방어가 될까요?

0

125

2

required 포트에 관해서

0

87

2

혹시 다음 편은 언제쯤 오픈할까요?

0

161

2

서비스 단위 테스트 코드 작성

0

92

2

domain 모듈에 entity를 정의한다고 했을때

0

91

2

여러 엔티티의 조합으로 리포트를 제공해야할 때

0

75

2