1. 문제 상황
진행 중인 프로젝트의 테스트 코드의 가독성이 (작성자인 나에게조차...) 가독성이 좋지 않은 것 같아 테스트 코드를 전반적으로 리팩토링하고 있다.
그 중 진행중인 작업 중 하나가 Test Fixture를 클래스로 관리하는 것이다.
현재 프로젝트는 각 계층의 의존성을 분리하기 위해 멀티 모듈을 사용하고 있다. Controller와 Service는 api 모듈, Entity와 DAO는 domain 모듈에서 관리하고 있다.
그렇기 때문에 DTO를 반환하는 Fixture 클래스는 api 모듈, 엔티티를 반환하는 Fixture 클래스는 domain 모듈에서 관리하기로 결정하였다.
하지만 아래 사진처럼 api 모듈에서 domain 모듈에 있는 Fixture을 불러올 수 없는 문제가 발생하였다.
2. 문제 원인
멀티 모듈 프로젝트에서 각 모듈은 jar로 만들어지고, 다른 모듈에서는 jar를 가져다 사용한다. 이때 빌드된 jar에는 테스트 관련 파일이 포함되지 않기 때문에 다른 모듈의 Test에 있는 클래스를 사용할 수 없는 것이다.
3. 해결 방법
1) 필요한 Fixture 클래스를 두 모듈에 작성한다 → 코드의 중복 발생, 변경사항 발생 시 각각 수정해주어야 함
2) Fixture 클래스를 모아두는 테스트 전용 모듈을 만든다 → 실제 코드와의 거리가 멀어져 응집도가 떨어짐, 테스트 전용 코드임에도 외부에 노출됨
이러한 문제를 해결하기 위해 Gradle의 java-test-fixtures 플러그인을 사용할 수 있다.
plugins {
id 'java'
id 'java-library' // 추가
id 'java-test-fixtures' // 추가
id 'maven-publish' // 추가
}
먼저 Fixtures 클래스를 위치시킬 모듈(이 프로젝트에서는 domain 모듈)에 플러그인을 추가한다.
그러면 위와 같이 testFixtures 디렉토리를 생성할 수 있게 된다.
** testFixtures 패키지는 스스로 만들어지는 것이 아니므로 직접 만들어야 한다 !! (처음에 나는 알아서 추가되는줄 🫠)
이제 필요한 Fixture 클래스는 testFixtures 패키지 내에서 생성해주면 된다.
Fixture 클래스를 '사용할' 모듈(이 프로젝트에서는 api 모듈)에서는 testFixture를 사용하기 위해 아래와 같이 build.gradle에 의존성을 추가해주어야 한다.
testImplementation(testFixtures(project(':packy-domain')))
4. 결과
Import class가 뜨는 것을 통해 이제 정상적으로 domain 모듈의 Fixture 클래스를 api 모듈에서 가져다 사용할 수 있는 것을 확인할 수 있다 : )
Reference
- https://toss.tech/article/how-to-manage-test-dependency-in-gradle
- https://bottom-to-top.tistory.com/58
- https://medium.com/@jojiapp/gradle-multi-module%EC%97%90%EC%84%9C-testfixtures%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%98%EC%97%AC-%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%BD%94%EB%93%9C-%EC%A4%91%EB%B3%B5-%EC%A4%84%EC%9D%B4%EA%B8%B0-3a4737f574f