Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 13a4545

Browse files
feat: Request와 Response를 Asciidoc으로 만들 때 그리는 설정 변경
1 parent b65d305 commit 13a4545

File tree

6 files changed

+173
-96
lines changed

6 files changed

+173
-96
lines changed

‎.idea/misc.xml

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎build.gradle.kts

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@ repositories {
1616
mavenCentral()
1717
}
1818

19-
extra["snippetsDir"] = file("build/generated-snippets")
20-
2119
dependencies {
2220
implementation("org.springframework.boot:spring-boot-starter-web")
2321
implementation("org.springframework.boot:spring-boot-starter-validation")
@@ -29,9 +27,11 @@ dependencies {
2927
// Spring Rest Docs
3028
testImplementation("com.epages:restdocs-api-spec-mockmvc:0.11.3")
3129
testImplementation("org.springframework.restdocs:spring-restdocs-mockmvc")
30+
asciidoctor("org.springframework.restdocs:spring-restdocs-asciidoctor:2.0.3.RELEASE")
3231

3332
// Mockito-Kotlin
34-
// testImplementation("com.nhaarman.mockitokotlin2:mockito-kotlin:2.2.0")
33+
testImplementation("com.nhaarman.mockitokotlin2:mockito-kotlin:2.2.0")
34+
testImplementation("org.mockito:mockito-inline:2.21.0")
3535

3636
// JUnit5...etc
3737
testImplementation("org.springframework.boot:spring-boot-starter-test")
@@ -48,13 +48,13 @@ tasks.withType<Test> {
4848
useJUnitPlatform()
4949
}
5050

51-
//val snippetsDir = "./target/classes/static/docs"
52-
//
53-
//tasks.test {
54-
// outputs.dir(snippetsDir)
55-
//}
56-
//
57-
//tasks.asciidoctor {
58-
// inputs.dir(snippetsDir)
59-
//// dependsOn(test)
60-
//}
51+
val asciidocDirectoryPath = "build/generated-snippets"
52+
53+
tasks.test {
54+
outputs.dir(asciidocDirectoryPath)
55+
}
56+
57+
tasks.asciidoctor {
58+
inputs.dir(asciidocDirectoryPath)
59+
dependsOn(tasks.test)
60+
}

‎src/docs/asciidoc/api-guide.adoc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
= Student
2+
3+
== Student 조회
4+
5+
include::{snippets}/testA/curl-request.adoc[]
6+
include::{snippets}/testA/http-request.adoc[]
7+
include::{snippets}/testA/http-response.adoc[]
8+
include::{snippets}/testA/httpie-request.adoc[]
9+
include::{snippets}/testA/request-body.adoc[]
10+
include::{snippets}/testA/response-body.adoc[]

‎src/main/resources/application.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
spring:
1+
server:
22
port: 6180
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.j.docs.common
2+
3+
import org.springframework.restdocs.operation.preprocess.Preprocessors.*
4+
5+
fun getDocumentRequest() =
6+
preprocessRequest(
7+
modifyUris()
8+
.scheme("http")
9+
.host("127.0.0.1")
10+
.port(6180),
11+
prettyPrint(),
12+
)
13+
14+
fun getDocumentResponse() = preprocessResponse(prettyPrint())

‎src/test/kotlin/com/j/docs/student/controller/StudentControllerTest.kt

Lines changed: 134 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,17 @@ package com.j.docs.student.controller
33
import com.epages.restdocs.apispec.MockMvcRestDocumentationWrapper.document
44
import com.epages.restdocs.apispec.ResourceDocumentation
55
import com.epages.restdocs.apispec.ResourceSnippetParameters
6-
import com.epages.restdocs.apispec.SimpleType
76
import com.j.docs.common.createRequest
7+
import com.j.docs.common.getDocumentRequest
8+
import com.j.docs.common.getDocumentResponse
89
import com.j.docs.common.response.CommonResponse
910
import com.j.docs.common.toObject
10-
import com.j.docs.student.controller.request.StudentCreationRequest
11+
import com.j.docs.student.controller.response.StudentAllSearchResponse
12+
import com.j.docs.student.dto.StudentSearchDto
1113
import com.j.docs.student.service.StudentCreationService
1214
import com.j.docs.student.service.StudentSearchService
13-
import org.assertj.core.api.Assertions.assertThat
1415
import org.junit.jupiter.api.Test
15-
import org.mockito.BDDMockito.*
16+
import org.mockito.BDDMockito.given
1617
import org.springframework.beans.factory.annotation.Autowired
1718
import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs
1819
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
@@ -21,6 +22,7 @@ import org.springframework.boot.test.mock.mockito.MockBean
2122
import org.springframework.http.HttpMethod
2223
import org.springframework.restdocs.payload.JsonFieldType
2324
import org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath
25+
import org.springframework.restdocs.payload.PayloadDocumentation.responseFields
2426
import org.springframework.test.web.servlet.MockMvc
2527
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status
2628

@@ -38,95 +40,146 @@ internal class StudentControllerTest {
3840
@MockBean
3941
private lateinit var studentSearchService: StudentSearchService
4042

41-
@Test
42-
fun `학생 등록하기 - CREATED`() {
43-
willDoNothing().given(
44-
studentCreationService.create(
45-
studentFirstName = "진혁",
46-
studentLastName = "",
47-
studentGrade = 3,
48-
studentClassroom = 4,
49-
studentNumber = 17,
50-
)
51-
)
43+
private val savedStudents = listOf(
44+
StudentSearchDto(1, "진혁 이", "3417"),
45+
StudentSearchDto(2, "진혁 리", "3517"),
46+
)
5247

53-
val requestBody = StudentCreationRequest(
54-
student = StudentCreationRequest.StudentInfo(
55-
firstName = "진혁",
56-
lastName = "",
57-
grade = 3,
58-
classroom = 4,
59-
number = 17,
60-
)
61-
)
48+
@Test
49+
fun `모든 학생 조회하기 - OK`() {
50+
given(studentSearchService.searchAll())
51+
.willReturn(savedStudents)
6252

6353
val result = mockMvc.perform(
64-
createRequest(
65-
httpMethod = HttpMethod.POST,
54+
createRequest<Nothing>(
55+
httpMethod = HttpMethod.GET,
6656
url = "/students",
67-
requestBody = requestBody,
6857
))
69-
.andExpect(status().isCreated)
58+
.andExpect(status().isOk)
7059
.andDo(
7160
document(
72-
"학생 등록하기 - CREATED",
73-
"",
74-
false,
75-
ResourceDocumentation.resource(
76-
ResourceSnippetParameters.builder()
77-
.requestFields(
78-
fieldWithPath("student.firstName")
79-
.type(SimpleType.STRING)
80-
.description("학생의 이름(first name)"),
81-
fieldWithPath("student.lastName")
82-
.type(SimpleType.STRING)
83-
.description("학생의 성(last name)"),
84-
fieldWithPath("student.grade")
85-
.type(SimpleType.INTEGER)
86-
.description("학생의 학년"),
87-
fieldWithPath("student.classroom")
88-
.type(SimpleType.INTEGER)
89-
.description("학생의 반"),
90-
fieldWithPath("student.number")
91-
.type(SimpleType.INTEGER)
92-
.description("학생의 번호"),
93-
).responseFields(
94-
fieldWithPath("response")
95-
.type(JsonFieldType.NULL)
96-
.description("응답 데이터 없음"),
97-
fieldWithPath("errorCode")
98-
.type(SimpleType.STRING)
99-
.description("에러 코드"),
100-
fieldWithPath("errorMessage")
101-
.type(SimpleType.STRING)
102-
.description("에러 메시지"),
103-
).build()
104-
)
61+
"testA",
62+
getDocumentRequest(),
63+
getDocumentResponse(),
64+
responseFields(
65+
fieldWithPath("response.students")
66+
.type(JsonFieldType.ARRAY)
67+
.description("조회한 학생들"),
68+
fieldWithPath("response.students[].id")
69+
.type(JsonFieldType.NUMBER)
70+
.description("학생 아이디"),
71+
fieldWithPath("response.students[].name")
72+
.type(JsonFieldType.STRING)
73+
.description("학생 이름"),
74+
fieldWithPath("response.students[].gradeClassNumber")
75+
.type(JsonFieldType.STRING)
76+
.description("학생 학년-반-번호"),
77+
fieldWithPath("errorCode")
78+
.type(JsonFieldType.NULL)
79+
.description("에러 코드"),
80+
fieldWithPath("errorMessage")
81+
.type(JsonFieldType.NULL)
82+
.description("에러 메시지"),
83+
),
10584
)
10685
)
10786
.andReturn()
10887
.response
10988
.contentAsString
110-
.toObject<CommonResponse<Nothing>>()
111-
112-
// verify(studentCreationService).create(
113-
// studentFirstName = "진혁",
114-
// studentLastName = "이",
115-
// studentGrade = 3,
116-
// studentClassroom = 4,
117-
// studentNumber = 17,
118-
// )
119-
then(studentCreationService)
120-
.should()
121-
.create(
122-
studentFirstName = "진혁",
123-
studentLastName = "",
124-
studentGrade = 3,
125-
studentClassroom = 4,
126-
studentNumber = 17,
127-
)
89+
.toObject<CommonResponse<StudentAllSearchResponse>>()
12890

129-
assertThat(result.errorCode).isNull()
130-
assertThat(result.errorMessage).isNull()
91+
println("result: $result")
13192
}
93+
94+
// @Test
95+
// fun `학생 등록하기 - CREATED`() {
96+
// willDoNothing().given(
97+
// studentCreationService.create(
98+
// studentFirstName = "진혁",
99+
// studentLastName = "이",
100+
// studentGrade = 3,
101+
// studentClassroom = 4,
102+
// studentNumber = 17,
103+
// )
104+
// )
105+
//
106+
// val requestBody = StudentCreationRequest(
107+
// student = StudentCreationRequest.StudentInfo(
108+
// firstName = "진혁",
109+
// lastName = "이",
110+
// grade = 3,
111+
// classroom = 4,
112+
// number = 17,
113+
// )
114+
// )
115+
//
116+
// val result = mockMvc.perform(
117+
// createRequest(
118+
// httpMethod = HttpMethod.POST,
119+
// url = "/students",
120+
// requestBody = requestBody,
121+
// ))
122+
// .andExpect(status().isCreated)
123+
// .andDo(
124+
// document(
125+
// "학생 등록하기 - CREATED",
126+
// "",
127+
// false,
128+
// ResourceDocumentation.resource(
129+
// ResourceSnippetParameters.builder()
130+
// .requestFields(
131+
// fieldWithPath("student.firstName")
132+
// .type(SimpleType.STRING)
133+
// .description("학생의 이름(first name)"),
134+
// fieldWithPath("student.lastName")
135+
// .type(SimpleType.STRING)
136+
// .description("학생의 성(last name)"),
137+
// fieldWithPath("student.grade")
138+
// .type(SimpleType.INTEGER)
139+
// .description("학생의 학년"),
140+
// fieldWithPath("student.classroom")
141+
// .type(SimpleType.INTEGER)
142+
// .description("학생의 반"),
143+
// fieldWithPath("student.number")
144+
// .type(SimpleType.INTEGER)
145+
// .description("학생의 번호"),
146+
// ).responseFields(
147+
// fieldWithPath("response")
148+
// .type(JsonFieldType.NULL)
149+
// .description("응답 데이터 없음"),
150+
// fieldWithPath("errorCode")
151+
// .type(SimpleType.STRING)
152+
// .description("에러 코드"),
153+
// fieldWithPath("errorMessage")
154+
// .type(SimpleType.STRING)
155+
// .description("에러 메시지"),
156+
// ).build()
157+
// )
158+
// )
159+
// )
160+
// .andReturn()
161+
// .response
162+
// .contentAsString
163+
// .toObject<CommonResponse<Nothing>>()
164+
//
165+
//// verify(studentCreationService).create(
166+
//// studentFirstName = "진혁",
167+
//// studentLastName = "이",
168+
//// studentGrade = 3,
169+
//// studentClassroom = 4,
170+
//// studentNumber = 17,
171+
//// )
172+
// then(studentCreationService)
173+
// .should()
174+
// .create(
175+
// studentFirstName = "진혁",
176+
// studentLastName = "이",
177+
// studentGrade = 3,
178+
// studentClassroom = 4,
179+
// studentNumber = 17,
180+
// )
181+
//
182+
// assertThat(result.errorCode).isNull()
183+
// assertThat(result.errorMessage).isNull()
184+
// }
132185
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /