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 c071949

Browse files
Update README.md
1 parent d6f661a commit c071949

File tree

1 file changed

+103
-0
lines changed

1 file changed

+103
-0
lines changed

‎README.md

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,106 @@
22
![Spring Rest Docs Logo](https://user-images.githubusercontent.com/48639421/127739359-3c4982f1-378e-4df0-b690-c4a0083ed3ad.png)
33

44
## Spring Rest Docs가 뭐야
5+
`Spring Rest Docs``Swagger`와 마찬가지로 `Open API`를 생성할 수 있는 라이브러리입니다.
6+
7+
`Swagger``Controller`단에 어노테이션을 붙여 `API`에 대한 설명을 덧붙일 수 있지만
8+
`Spring Rest Docs`는 테스트 코드를 작성함으로써 `Open API`를 구체화할 수 있습니다.
9+
10+
또한 `Swagger`는 어노테이션 기반이기 때문에 구체화한 정보에 대한 검증이 이루어지지 않고
11+
그에 따라 `API`가 변하면서 바뀌어야하는 조건에 대한 정확성과 무결성이 깨지게 됩니다.
12+
하지만 `Spring Rest Docs`는 테스트 코드에서 실제 `Request`가 오지 않았거나, `Response`에 대한 결과가 맞지 않거나,
13+
타입이 맞지 않는 등의 `실제와 다른 정보`를 검증이 가능합니다.
14+
따라서 `Open API`와 실제 `API`의 동작 방식간의 일관성을 유지할 수 있습니다.
15+
16+
## Spring Rest Docs 사용해보기
17+
```kotlin
18+
19+
@Test
20+
fun `모든 학생 조회하기 - OK`() {
21+
val returnValue = listOf(
22+
StudentSearchDto(
23+
studentId = 1,
24+
studentName = "jinhyeok lee",
25+
studentGradeClassNumber = "3417",
26+
),
27+
StudentSearchDto(
28+
studentId = 2,
29+
studentName = "jinhyuk lee",
30+
studentGradeClassNumber = "3517",
31+
),
32+
)
33+
34+
given(studentSearchService.searchAll())
35+
.willReturn(returnValue)
36+
37+
val result = mockMvc.perform(
38+
createRequest<Nothing>(
39+
httpMethod = HttpMethod.GET,
40+
url = "/students",
41+
))
42+
.andExpect(status().isOk)
43+
.andDo(
44+
document(
45+
"모든 학생 조회하기 - OK",
46+
getDocumentRequest(),
47+
getDocumentResponse(),
48+
responseFields(
49+
fieldWithPath("response.students")
50+
.type(JsonFieldType.ARRAY)
51+
.description("조회한 학생들"),
52+
fieldWithPath("response.students[].id")
53+
.type(JsonFieldType.NUMBER)
54+
.description("학생 아이디"),
55+
fieldWithPath("response.students[].name")
56+
.type(JsonFieldType.STRING)
57+
.description("학생 이름"),
58+
fieldWithPath("response.students[].gradeClassNumber")
59+
.type(JsonFieldType.STRING)
60+
.description("학생 학년-반-번호"),
61+
fieldWithPath("errorCode")
62+
.type(JsonFieldType.NULL)
63+
.description("에러 코드"),
64+
fieldWithPath("errorMessage")
65+
.type(JsonFieldType.NULL)
66+
.description("에러 메시지"),
67+
),
68+
),
69+
)
70+
.andReturn()
71+
.response
72+
.contentAsString
73+
.toObject<CommonResponse<StudentAllSearchResponse>>()
74+
75+
verify(studentSearchService).searchAll()
76+
77+
assertThat(result.errorCode).isNull()
78+
assertThat(result.errorMessage).isNull()
79+
assertThat(result.response).isNotNull
80+
assertThat(result.response!!.students)
81+
.map<Long> { it.id }
82+
.contains(1, 2)
83+
assertThat(result.response!!.students)
84+
.map<String> { it.name }
85+
.contains("jinhyeok lee", "jinhyuk lee")
86+
assertThat(result.response!!.students)
87+
.map<String> { it.gradeClassNumber }
88+
.contains("3417", "3517")
89+
}
90+
```
91+
테스트 프레임워크는 `BDD-Mockito`를 이용하였습니다.
92+
겉보기에는 컨트롤러를 테스트하는 코드로 보이지만 눈에 띄는 코드가 있습니다.
93+
`andDo` 메소드를 통해 `document`를 생성하는 코드입니다.
94+
여기서는 위에서 말했던 것처럼 `Request``Response`를 검증하는 역할을 합니다.
95+
96+
첫 번째 인자로는 `API`의 이름을 등록하고,
97+
두, 세 번째 인자로는 `Request``Response`에 대한 설정을 등록하는데
98+
여기서는 나중에 테스트 코드를 빌드하여 생성되는 `asciidoc`에서
99+
`Request``Response`를 예쁘게 찍기 위한 설정을 해두었습니다.
100+
101+
제일 중요한 건 마지막 인자입니다.
102+
여기서 `Response`를 검증하기 위해서는 `responseFields()` 메소드를,
103+
`Request`를 검증하기 위해서는 `requestFields()` 메소드를 사용합니다.
104+
다른 내용은 한 눈에 봐도 무슨 뜻인지 유추하기 쉽습니다.
105+
106+
이렇게 도큐먼트를 생성한 뒤에는 원래 테스트 하던 것처럼
107+
`verify` 해주고, 응답 `assertion` 하시면 됩니다.

0 commit comments

Comments
(0)

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