실행 환경
- Spring Boot 3.4.0
- Gradle 8.11.1
이슈
Junit5 의존성 주입간에 빌드 실패
해결 과정
실패 1
Baeldung이라는 Spring에 관한 많은 튜토리얼이 있는 사이트를 참고해서 빌드하려 했습니다. 오류의 내용은 대충 Gradle 9.0.X 버전부터 Spring Boot의 dependency automatic loading 기능이 폐기된다는 내용이었습니다. 하지만, 사진처럼 버전을 명시한채로 사용했기에 근본 원인은 아니었습니다. 스택오버플로우를 뒤져봐도 버전을 바꿔야한다는 약간 찜찜한 답변이 주였고, 결과적으로 버전을 바꿔도 오류가 뜨긴 마찬가지였습니다.
실패 2
Spring 공식 문서에서, 권장하는 Spring & Java 버전 조합을 제공하는 것이 떠올랐습니다.
그래서 "junit dependency for gradle 8.1.1" 키워드로 검색했는데 나오지 않았습니다, 방황하다가 geeksforgeeks 라는 사이트의 예제를 참고했습니다.
명시된 코드 중 두 부분을 확인했습니다. 이는 디펜던시 저장소(mavenCentral) 지정 및 테스트 작업 수행간 Junit을 사용한다는 내용의 코드였고, 기존 오류 발생 동안에도 포함시킨 내용이었기에 해결책이 되지 못했습니다.
repositories {
mavenCentral()
}
tasks.named('test') {
useJUnitPlatform()
}
실패 3
이후 시도해본 방법은 다음과 같습니다.
- 프로젝트에 Gradle이 정상 설치되었나 확인 (터미널 단축키 : F12, 명령어 : ./gradlew -v)
- Intellij 설정에서 빌드 주체를 (Gradle -> Intellij)로 변경 (File -> Settings)
- Gradle 클린 빌드, 디펜던시 캐시 삭제, 로깅 레벨 전체 (./gradlew clean build --refresh-dependencies --warning-mode all)
Gradle이 오류 발생시 에러를 문서화해서 제공해줬습니다.
(다만, 에러가 아닌 경고로 실패 1번 내용만 계속 표시해줬습니다)
오류 log로 서칭해도 명확한 답변을 찾긴 어려웠고, 디펜던시 충돌이 일어났다 정도로 가정했습니다.
이후 h2, spring boot test, archunit등의 테스트 관련 디펜던시를 제거해도 상황은 마찬가지였습니다.
실패 4
Junit 디펜던시 자체를 잘못 주입하고있나? 라는 생각이 들어 찾아보았습니다.
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.2'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.2'
jupiter은 junit engine을 구동하기 위한 구현체입니다.
결과적으로는,
Implementation - 코드 작성간 사용될 수 있는 클래스나 애노테이션 의존성을 추가하는 곳
=> "테스트 코드 작성"을 위한 API가 위치하는 것은 올바르다.
RuntimeOnly는 런타임에만 참조되는 의존성을 추가하는 곳
(런타임시 유일하게 사용할 의존성이라고 잘못 알고 있었습니다.)
=> "테스트 코드 실행" 을 위한 엔진이 위치하는 것은 올바르다.
실패 5
mvnrepository를 가서 무작정 찾아보기로 했다가 곧 생각을 고쳤습니다.
많은 라이브러리가 기능을 세분화하여 제공하기 위해 여러 모듈을 제공하는데, Junit은 그 숫자가 너무 많았습니다.
성공
junit 또한 gradle을 사용하여 빌드되니까, gradle 문서에서 문제를 찾을 수 있지 않을까 생각했습니다. (찾았습니다)
plugins {
id 'java'
id 'org.springframework.boot' version '3.4.0'
id 'io.spring.dependency-management' version '1.1.6'
}
group = 'com.sh'
version = '1.0'
java {
toolchain {
languageVersion = JavaLanguageVersion.of(17)
}
}
repositories {
mavenCentral()
}
dependencies {
// ...
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.2'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.2'
}
tasks.named('test') {
useJUnitPlatform()
}
결론
원래 빠르게 구현할땐 튜토리얼 사이트나 한국 블로그를 참고한 후, 자세한 지식이나 좀 더 근본있는 구현?이 필요할 때 공식 문서를 참고하는 방식을 사용했었습니다.
이번에 4시간을 쓰며 공식 문서의 소중함을 직접 체감했고, 앞으로는 적극 참고하겠다고 다짐했습니다.
'트러블 슈팅' 카테고리의 다른 글
ParameterizedTest 적용해보기 (0) | 2024.12.16 |
---|---|
Test Data Builder Class를 적용하기 전의 고찰 (0) | 2024.12.10 |
백준 3407번(맹세) 풀이 - Java 메모리 제한이 심한 문제 (1) | 2024.10.25 |
[VM/Ubuntn] 양방향 클립보드 공유 (0) | 2024.07.15 |