작성
·
101
·
수정됨
0
MemberRepositoryTest는 EntityManager
나 @DataJpaTest
등 Jpa와 깊게 관련되어있는 테스트로 이해됐습니다. EntityManager#flush()
가 잘 호출되는지 확인하는 부분도 그런 이유에서 이해됩니다.
하지만 테스트명이 MemberRepositoryTest인 점에서 헷갈리는 부분이 발생합니다. MemberRepository 인터페이스의 메서드를 테스트하는 것이 목적이라면 좀 더 추상화된 테스트를 작성하는 것이 옳지 않았나? 라는 것이 주된 궁금증입니다.
물론 Spring Data JPA 특성상 런타임에 구현체가 만들어지기 때문에, 테스트 대상은 인터페이스를 사용해야 한다는 것은 이해합니다만, 최소한 클래스명은 좀 더 구체적으로 작성해주는 것이 의도에 부합하지 않나? 해서 질문드립니다! 어떻게 생각하시나요?
답변 2
2
스프링 데이터 JPA와 같이 코드를 자동 생성하는 기술을 사용할 때 고민이 되는 부분입니다.
테스트는 오브젝트를 실행해야 하기 때문에 구현 클래스를 사용해야 하는데 스프링 데이터는 클래스를 런타임에 자동으로 만들어주기 때문에 이걸 테스트 할 수 있는 방법은 @DataJpaTest와 같이 스프링 컨테이너를 이용해서 JPA 환경을 만들고 인터페이스 타입의 빈을 가져와 테스트하는 것 뿐이죠.
그런데 특정 클래스 구현에 대한 단위 테스트가 아니라 통합 테스트라고 본다면 리포지토리 인터페이스에 현재 매핑되는 빈(bean)을 테스트 하는 것으로는 RespositoryTest가 자연스럽다고 생각됩니다. 그 인터페이스로부터 출발해서 뒤에 (메모리) DB까지 다 검증하는 테스트 코드이기 때문이죠.
비슷하게 애플리케이션 계층의 provided 인터페이스를 타고 테스트 하는 경우에도 스프링 컨테이너를 띄우는 통합테스트인 경우엔 테스트를 수행하면서 여러 계층과 기술이 통합되어서 테스트가 됩니다. 그게 테스트 만들기도 좋고, 실제와 유사하게 기능의 동작을 검증하는 것이 자연스럽기 때문에 애플리케이션 서비스에 대한 단위 테스트보다 더 선호되는 것이죠.
사실 인터페이스만 테스트할 방법이란 없습니다. 거기에 스텁을 만들어 넣고 테스트 한다면 아무런 가치가 없을 것이니까요. 대체로 리포지토리, DAO와 같은 코드는 DB 기능을 사용하는 애플리케이션의 인터페이스(자바의 인터페이스가 아니라 DB에 대한 시스템 입장에서 인터페이스)이기 때문에 그 자체로 테스트 한다는 것도 별 가치가 없습니다. 리포지토리 구현 클래스가 있다고 하더라도, EntityManager를 목킹해서 테스트 하는 건 테스트로서 별 가치를 주지 못하기 때문에 그렇습니다.
리포지토리에 정의된 기능이 비록 스프링 데이터가 자동으로 구현을 만들어주긴 하지만, 그 구현을 이끌어내는 관례가 인터페이스에 반영되어 있기 때문에 지금 코드가 충분히 인터페이스 테스트이기도 하다는 생각인데요.
혹시 더 나은 이름을 생각하신 게 있으신가요.
1
안녕하세요, 인프런 AI 인턴입니다.
Dompoo님의 질문은 테스트 클래스의 이름을 통해 테스트의 목적과 의도를 명확히 표현할 필요성에 대한 고찰을 주제로 하고 있습니다. 테스트 클래스나 테스트 메서드의 이름은 코드 유지보수성과 가독성 측면에서 중요합니다. 다음은 이와 관련해 유사한 답변과 자료를 제공하고자 합니다.
테스트 클래스의 이름은 단순히 어떤 클래스나 메서드를 테스트하는지를 넘어서, 그 테스트의 목적과 대상의 특성을 잘 나타내야 할 필요가 있습니다. 일반적으로 다음과 같은 명명 규칙을 적용할 수 있습니다:
명확한 대상 식별: 테스트 클래스의 이름은 대상 클래스나 인터페이스의 역할을 설명해야 합니다. 예를 들어, MemberRepositoryTest
는 특정 리포지토리를 테스트하는 클래스임을 명확히 표현할 수 있습니다.
테스트 의도 반영: 이름에 테스트의 특수한 목적이나 조건을 포함시킴으로써 더 많은 정보를 제공할 수 있습니다. 예를 들어, MemberRepositoryDataJpaIntegrationTest
라면, 단순히 리포지토리의 인터페이스뿐 아니라 JPA 관련 통합 테스트를 실행한다는 점을 명확히 할 수 있습니다.
토비님의 강의에서 다루어진 @Transactional
및 JPA와 관련된 테스트에 대한 내용은 자주 논의되곤 합니다. 테스트에서의 @Transactional 사용에 대해 질문이 있습니다.에서는 테스트 클래스와 메서드가 경계와 의미를 어떻게 명확히 할 것인지에 대해 다루고 있습니다. 이 답변에서는 JPA와 관련된 테스트 방법뿐 아니라 명명과 설계 측면까지도 넓게 다룹니다.
현재 담포님이 제기하신 테스트 클래스의 명명과 관련된 고민은 소프트웨어 개발에서 지속적으로 고려해야 할 주제입니다. 위의 자료를 참고하여 명명 규칙을 재검토하고, 보다 명확하고 유지보수하기 쉬운 테스트 코드를 설계하는 데 도움이 되길 바랍니다.
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.
먼저 빠르고 양질의 답변에 너무 감사드립니다!! 강의 정말 잘 보고 있습니다. ㅎㅎ
먼저 제가 이런 질문을 드렸던 배경을 설명드리고 싶습니다. 저는 원래 다음과 같이 생각했습니다.
그래서 MemberRepositoryTest라는 이름의 테스트가 JPA에 깊게 관여되어있던 것이 부자연스럽게 느껴졌습니다.
저도 토비님의 의견에 전적으로 동의합니다. 인터페이스란 단위를 지키기 위해서 짜는 테스트는 실용적 가치가 매우 작을 것 같습니다. 따라서 실제 엔티티매니저와 @DataJpaTest를 통해서 짜는 통합테스트의 형태는 매우 마음에 듭니다.
따라서 인터페이스 -> 스프링 DI에 의한 구현체로 이어지는 전체 흐름을 테스트하시려는 의도셨다면 현재 테스트명이 그 목적에 가장 잘 부합하는 것 같습니다.
테스트의 목적에 대한 새로운 시선을 얻게 되는 것 같습니다. 감사합니다!