-
Notifications
You must be signed in to change notification settings - Fork 0
[Feat] RestDocs, Test 환경설정 #17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -2,6 +2,7 @@ plugins { | |||||||||||||||||||||||||||||||
| java | ||||||||||||||||||||||||||||||||
| id("org.springframework.boot") version "3.5.9" | ||||||||||||||||||||||||||||||||
| id("io.spring.dependency-management") version "1.1.7" | ||||||||||||||||||||||||||||||||
| id("org.asciidoctor.jvm.convert") version "4.0.5" | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| group = "com.umc" | ||||||||||||||||||||||||||||||||
|
|
@@ -19,6 +20,7 @@ configurations { | |||||||||||||||||||||||||||||||
| compileOnly { | ||||||||||||||||||||||||||||||||
| extendsFrom(configurations.annotationProcessor.get()) | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| create("asciidoctorExt") | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| repositories { | ||||||||||||||||||||||||||||||||
|
|
@@ -54,9 +56,6 @@ dependencies { | |||||||||||||||||||||||||||||||
| annotationProcessor("com.querydsl:querydsl-apt:${queryDslVersion}:jakarta") | ||||||||||||||||||||||||||||||||
| annotationProcessor("jakarta.annotation:jakarta.annotation-api") | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| // APT가 jakarta 클래스를 로딩할 수 있게 명시 | ||||||||||||||||||||||||||||||||
| annotationProcessor("jakarta.persistence:jakarta.persistence-api") | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| // --- Database --- | ||||||||||||||||||||||||||||||||
| implementation("org.flywaydb:flyway-core") | ||||||||||||||||||||||||||||||||
| implementation("org.flywaydb:flyway-database-postgresql") | ||||||||||||||||||||||||||||||||
|
|
@@ -95,8 +94,39 @@ dependencies { | |||||||||||||||||||||||||||||||
| testImplementation("org.testcontainers:testcontainers") | ||||||||||||||||||||||||||||||||
| testImplementation("org.testcontainers:junit-jupiter") | ||||||||||||||||||||||||||||||||
| testImplementation("org.testcontainers:postgresql") | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| // --- Spring REST Docs --- | ||||||||||||||||||||||||||||||||
| "asciidoctorExt"("org.springframework.restdocs:spring-restdocs-asciidoctor") | ||||||||||||||||||||||||||||||||
| testImplementation("org.springframework.restdocs:spring-restdocs-mockmvc") | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| tasks.withType<Test> { | ||||||||||||||||||||||||||||||||
| useJUnitPlatform() | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| val snippetsDir = file("build/generated-snippets") | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| tasks.test { | ||||||||||||||||||||||||||||||||
| outputs.dir(snippetsDir) | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
Comment on lines
+110
to
+113
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Issue #16의 테스트 실패 로그 요구사항이 누락되었습니다. Issue #16에서는 "테스트 실패 시 상세 로그 출력 구성"을 명시적으로 요구하고 있습니다. 현재 코드는 커밋 메시지("test task 간략화")를 보면 의도적인 간소화로 보이나, 이는 Issue 요구사항과 불일치합니다. 다음 중 하나를 선택하시기 바랍니다:
🔎 테스트 실패 로그 출력 예시이전 리뷰 댓글에서 언급된 것처럼 상세 로그 출력을 위해 다음과 같이 구성할 수 있습니다: tasks.test {
outputs.dir(snippetsDir)
-
+
+ testLogging {
+ events("passed", "skipped", "failed")
+ showExceptions = true
+ showCauses = true
+ showStackTraces = true
+ exceptionFormat = org.gradle.api.tasks.testing.logging.TestExceptionFormat.FULL
+ }
}📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| tasks.asciidoctor { | ||||||||||||||||||||||||||||||||
| inputs.dir(snippetsDir) | ||||||||||||||||||||||||||||||||
| configurations("asciidoctorExt") | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| sources { | ||||||||||||||||||||||||||||||||
| include("**/index.adoc") | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| baseDirFollowsSourceDir() | ||||||||||||||||||||||||||||||||
| dependsOn(tasks.test) | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| tasks.bootJar { | ||||||||||||||||||||||||||||||||
| dependsOn(tasks.asciidoctor) | ||||||||||||||||||||||||||||||||
| from(tasks.asciidoctor.get().outputDir) { | ||||||||||||||||||||||||||||||||
| into("static/docs") | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| ifndef::snippets[] | ||
| :snippets: ../../build/generated-snippets | ||
| endif::[] | ||
| = UMC Product REST API 문서 | ||
| :doctype: book | ||
| :icons: font | ||
| :source-highlighter: highlightjs | ||
| :toc: left | ||
| :toclevels: 2 | ||
| :sectlinks: | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| package com.umc.product.support; | ||
|
|
||
|
|
||
| import com.fasterxml.jackson.databind.ObjectMapper; | ||
| import org.springframework.beans.factory.annotation.Autowired; | ||
| import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs; | ||
| import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; | ||
| import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; | ||
| import org.springframework.context.annotation.Import; | ||
| import org.springframework.restdocs.mockmvc.RestDocumentationResultHandler; | ||
| import org.springframework.test.web.servlet.MockMvc; | ||
|
|
||
| @WebMvcTest( | ||
| ) | ||
| @Import({ | ||
| RestDocsConfig.class, | ||
| }) | ||
| @AutoConfigureMockMvc(addFilters = false) | ||
| @AutoConfigureRestDocs | ||
|
Comment on lines
+13
to
+19
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# DocumentationTest를 extends하는 클래스들과 그들의 @WebMvcTest 설정 확인
rg -n "extends DocumentationTest" --type java -A 15 -B 2Repository: UMC-PRODUCT/umc-product-server Length of output: 56 🏁 Script executed: #!/bin/bash
# 1. DocumentationTest.java 파일 확인
echo "=== DocumentationTest.java 내용 ==="
find . -name "DocumentationTest.java" -type f | head -5
# 2. DocumentationTest를 import하거나 참조하는 파일들 검색
echo -e "\n=== DocumentationTest를 참조하는 파일들 ==="
rg "DocumentationTest" --type java
# 3. REST Docs 관련 @WebMvcTest 사용 패턴 확인
echo -e "\n=== @WebMvcTest 사용 패턴 ==="
rg "@WebMvcTest" --type java -A 3Repository: UMC-PRODUCT/umc-product-server Length of output: 627 🏁 Script executed: #!/bin/bash
# DocumentationTest.java 전체 내용 읽기
cat -n src/test/java/com/umc/product/support/DocumentationTest.javaRepository: UMC-PRODUCT/umc-product-server Length of output: 1208 🏁 Script executed: #!/bin/bash
# 1. RestDocsConfig 검색
echo "=== RestDocsConfig 파일 확인 ==="
find . -name "RestDocsConfig.java" -type java | head -5
# 2. RestDocumentationResultHandler 사용하는 클래스 찾기
echo -e "\n=== RestDocumentationResultHandler 참조 ==="
rg "RestDocumentationResultHandler" --type java -B 3 -A 3
# 3. REST Docs 관련 테스트 클래스들
echo -e "\n=== Test 클래스들 현황 ==="
fd ".*Test\.java$" src/test/java --type f | head -20Repository: UMC-PRODUCT/umc-product-server Length of output: 3095 🏁 Script executed: #!/bin/bash
# 1. 모든 Test 클래스 찾기 (고정된 find 명령)
echo "=== 모든 Test 클래스 ==="
find src/test/java -name "*Test.java" -type f
# 2. 더 광범위한 extends DocumentationTest 검색
echo -e "\n=== DocumentationTest 상속 여부 ==="
rg "extends\s+DocumentationTest|DocumentationTest\s*{" --type java -B 2 -A 8
# 3. @WebMvcTest 사용하는 모든 클래스
echo -e "\n=== @WebMvcTest 사용 클래스 ==="
rg "@WebMvcTest" --type java -B 5Repository: UMC-PRODUCT/umc-product-server Length of output: 1032 🏁 Script executed: #!/bin/bash
# @WebMvcTest()의 빈 controllers 파라미터 동작 확인
cat > /tmp/check_webmvctest.py << 'EOF'
# @WebMvcTest() with empty controllers parameter behavior
# According to Spring Boot documentation:
# - @WebMvcTest() with no controllers specified will load ALL controllers
# - This can cause issues because the context becomes too large
# - For a base class meant to be extended, this is suboptimal design
print("Spring Boot @WebMvcTest() behavior:")
print("1. @WebMvcTest() - loads ALL controllers in the application context")
print("2. @WebMvcTest(controllers = SpecificController.class) - loads ONLY specified controller")
print("\nFor a base class meant to be inherited:")
print("- Having @WebMvcTest() (all controllers) is problematic")
print("- Subclasses cannot override/narrow the controller scope")
print("- Better approach: Keep base class minimal, let subclasses specify controllers")
EOF
python /tmp/check_webmvctest.py
# 2. 실제 Spring Boot 권장사항 확인
echo -e "\n=== 결론 ==="
echo "DocumentationTest.java의 현재 상태:"
echo "- @WebMvcTest() 빈 파라미터 사용: 모든 컨트롤러 로드 (불필요)"
echo "- 아직 상속하는 클래스 없음: 현재 사용되지 않는 상태"Repository: UMC-PRODUCT/umc-product-server Length of output: 160 REST Docs 테스트 기반 클래스 설정이 잘 구성되었습니다.
🤖 Prompt for AI Agents |
||
| public class DocumentationTest { | ||
|
|
||
| @Autowired | ||
| protected MockMvc mockMvc; | ||
|
|
||
| @Autowired | ||
| protected RestDocumentationResultHandler restDocsHandler; | ||
|
|
||
| @Autowired | ||
| protected ObjectMapper objectMapper; | ||
|
|
||
| } | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,22 @@ | ||||||||||||||||||||||||||||||||||
| package com.umc.product.support; | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| import org.springframework.boot.test.context.TestConfiguration; | ||||||||||||||||||||||||||||||||||
| import org.springframework.context.annotation.Bean; | ||||||||||||||||||||||||||||||||||
| import org.springframework.restdocs.mockmvc.MockMvcRestDocumentation; | ||||||||||||||||||||||||||||||||||
| import org.springframework.restdocs.mockmvc.RestDocumentationResultHandler; | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| import static org.springframework.restdocs.operation.preprocess.Preprocessors.*; | ||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧹 Nitpick | 🔵 Trivial 와일드카드 static import 사용 검토 (선택적) 와일드카드 static import( 🔎 명시적 import로 변경하는 제안-import static org.springframework.restdocs.operation.preprocess.Preprocessors.*;
+import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessRequest;
+import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessResponse;
+import static org.springframework.restdocs.operation.preprocess.Preprocessors.prettyPrint;🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| @TestConfiguration | ||||||||||||||||||||||||||||||||||
| public class RestDocsConfig { | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| @Bean | ||||||||||||||||||||||||||||||||||
| public RestDocumentationResultHandler restDocsMockMvcConfigurationCustomizer() { | ||||||||||||||||||||||||||||||||||
| return MockMvcRestDocumentation.document( | ||||||||||||||||||||||||||||||||||
| "{class-name}/{method-name}", | ||||||||||||||||||||||||||||||||||
| preprocessRequest(prettyPrint()), | ||||||||||||||||||||||||||||||||||
| preprocessResponse(prettyPrint()) | ||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
|
Comment on lines
+13
to
+20
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion | 🟠 Major 메서드명이 반환 타입과 불일치 메서드명 현재 코드는 Result Handler를 반환하므로 메서드명이 혼란을 야기할 수 있습니다. 메서드명을 반환 타입과 용도에 맞게 변경하는 것을 권장합니다. 🔎 메서드명 개선 제안 @Bean
-public RestDocumentationResultHandler restDocsMockMvcConfigurationCustomizer() {
+public RestDocumentationResultHandler restDocsHandler() {
return MockMvcRestDocumentation.document(
"{class-name}/{method-name}",
preprocessRequest(prettyPrint()),
preprocessResponse(prettyPrint())
);
}참고: 설정 내용 자체(문서 경로 패턴, pretty-print 전처리)는 REST Docs 표준 패턴을 잘 따르고 있으며 적절합니다. 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| package com.umc.product.support; | ||
|
|
||
|
|
||
| import org.springframework.boot.test.context.SpringBootTest; | ||
|
|
||
| @SpringBootTest | ||
| public abstract class UseCaseTestSupport { | ||
|
Comment on lines
+6
to
+7
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Find all test classes extending UseCaseTestSupport
rg -n "extends UseCaseTestSupport" --type java -C 10Repository: UMC-PRODUCT/umc-product-server Length of output: 56 🏁 Script executed: #!/bin/bash
# First, check if the file exists and read its contents
echo "=== Checking UseCaseTestSupport.java ==="
find . -name "UseCaseTestSupport.java" -type f
echo -e "\n=== Searching for test files that might extend it ==="
find ./src/test -name "*.java" -type f | head -20
echo -e "\n=== Looking for any references to UseCaseTestSupport ==="
rg "UseCaseTestSupport" --type javaRepository: UMC-PRODUCT/umc-product-server Length of output: 647 🏁 Script executed: #!/bin/bash
cat -n ./src/test/java/com/umc/product/support/UseCaseTestSupport.javaRepository: UMC-PRODUCT/umc-product-server Length of output: 303 🏁 Script executed: #!/bin/bash
echo "=== UmcProductApplicationTests.java ==="
cat -n ./src/test/java/com/umc/product/UmcProductApplicationTests.java
echo -e "\n=== DocumentationTest.java ==="
cat -n ./src/test/java/com/umc/product/support/DocumentationTest.java
echo -e "\n=== Checking for UseCase classes in src ==="
find ./src/main -name "*UseCase.java" -type f | head -10Repository: UMC-PRODUCT/umc-product-server Length of output: 1628 🏁 Script executed: #!/bin/bash
echo "=== Checking for any service/use case patterns in the project ==="
find ./src/main -name "*.java" -type f | grep -E "(Service|UseCase)" | head -10
echo -e "\n=== Checking application.yml or application.properties for context hints ==="
find ./src -name "application*.yml" -o -name "application*.properties"Repository: UMC-PRODUCT/umc-product-server Length of output: 254
현재 이 클래스는 공유할 테스트 설정이나 유틸리티가 없는 빈 추상 클래스입니다. UseCase는 단일 책임 원칙을 따르는 단위 테스트 대상이므로, 다음 중 하나를 권장합니다:
프로젝트의 🤖 Prompt for AI Agents |
||
|
|
||
|
|
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| //==== Request Fields | ||
| |=== | ||
| |Path|Type|Optional|Description | ||
|
|
||
| {{#fields}} | ||
|
|
||
| |{{#tableCellContent}}`+{{path}}+`{{/tableCellContent}} | ||
| |{{#tableCellContent}}`+{{type}}+`{{/tableCellContent}} | ||
| |{{#tableCellContent}}{{#optional}}O{{/optional}}{{/tableCellContent}} | ||
| |{{#tableCellContent}}{{description}}{{/tableCellContent}} | ||
|
|
||
| {{/fields}} | ||
|
|
||
| |=== |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| //==== Response Fields | ||
| |=== | ||
| |Path|Type|Optional|Description | ||
|
|
||
| {{#fields}} | ||
|
|
||
| |{{#tableCellContent}}`+{{path}}+`{{/tableCellContent}} | ||
| |{{#tableCellContent}}`+{{type}}+`{{/tableCellContent}} | ||
| |{{#tableCellContent}}{{#optional}}O{{/optional}}{{/tableCellContent}} | ||
| |{{#tableCellContent}}{{description}}{{/tableCellContent}} | ||
|
|
||
| {{/fields}} | ||
|
|
||
| |=== |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🌐 Web query:
org.asciidoctor.jvm.convert gradle plugin latest version 2025💡 Result:
The latest release in 2025 is version 4.0.4 (released January 13, 2025). [1][2]
Sources:
🌐 Web query:
org.asciidoctor.jvm.convert 4.0.5 gradle plugin💡 Result:
Short answer: There is no org.asciidoctor.jvm.convert plugin version 4.0.5 on the Gradle Plugin Portal — the latest published for that plugin id is 4.0.3 (published 20 Jul 2024). Other Asciidoctor JVM plugins (org.asciidoctor.jvm.base, .pdf, .gems, .js.convert, etc.) do have 4.0.5 releases. [1][2][3]
If you want, I can watch the Gradle Plugin Portal for a 4.0.5 release of org.asciidoctor.jvm.convert or suggest a migration path (use 4.x suite or the 1.5.x "org.asciidoctor.convert" legacy plugin).
플러그인 버전을 4.0.3으로 수정하세요.
org.asciidoctor.jvm.convert버전 4.0.5는 존재하지 않습니다. Gradle Plugin Portal의 최신 버전은 4.0.3(2024년 7월 20일 발표)입니다. 현재 버전은 플러그인 해석 실패를 야기할 것입니다.🤖 Prompt for AI Agents