Spring Rest Docs
는 Swagger
와 마찬가지로 Open API
를 생성할 수 있는 라이브러리입니다.
Swagger
는 Controller
단에 어노테이션을 붙여 API
에 대한 설명을 덧붙일 수 있지만
Spring Rest Docs
는 테스트 코드를 작성함으로써 Open API
를 구체화할 수 있습니다.
또한 Swagger
는 어노테이션 기반이기 때문에 구체화한 정보에 대한 검증이 이루어지지 않고
그에 따라 API
가 변하면서 바뀌어야하는 조건에 대한 정확성과 무결성이 깨지게 됩니다.
하지만 Spring Rest Docs
는 테스트 코드에서 실제 Request
가 오지 않았거나, Response
에 대한 결과가 맞지 않거나,
타입이 맞지 않는 등의 실제와 다른 정보
를 검증이 가능합니다.
따라서 Open API
와 실제 API
의 동작 방식간의 일관성을 유지할 수 있습니다.
@Test
fun `모든 학생 조회하기 - OK`() {
val returnValue = listOf(
StudentSearchDto(
studentId = 1,
studentName = "jinhyeok lee",
studentGradeClassNumber = "3417",
),
StudentSearchDto(
studentId = 2,
studentName = "jinhyuk lee",
studentGradeClassNumber = "3517",
),
)
given(studentSearchService.searchAll())
.willReturn(returnValue)
val result = mockMvc.perform(
createRequest<Nothing>(
httpMethod = HttpMethod.GET,
url = "/students",
))
.andExpect(status().isOk)
.andDo(
document(
"모든 학생 조회하기 - OK",
getDocumentRequest(),
getDocumentResponse(),
responseFields(
fieldWithPath("response.students")
.type(JsonFieldType.ARRAY)
.description("조회한 학생들"),
fieldWithPath("response.students[].id")
.type(JsonFieldType.NUMBER)
.description("학생 아이디"),
fieldWithPath("response.students[].name")
.type(JsonFieldType.STRING)
.description("학생 이름"),
fieldWithPath("response.students[].gradeClassNumber")
.type(JsonFieldType.STRING)
.description("학생 학년-반-번호"),
fieldWithPath("errorCode")
.type(JsonFieldType.NULL)
.description("에러 코드"),
fieldWithPath("errorMessage")
.type(JsonFieldType.NULL)
.description("에러 메시지"),
),
),
)
.andReturn()
.response
.contentAsString
.toObject<CommonResponse<StudentAllSearchResponse>>()
verify(studentSearchService).searchAll()
assertThat(result.errorCode).isNull()
assertThat(result.errorMessage).isNull()
assertThat(result.response).isNotNull
assertThat(result.response!!.students)
.map<Long> { it.id }
.contains(1, 2)
assertThat(result.response!!.students)
.map<String> { it.name }
.contains("jinhyeok lee", "jinhyuk lee")
assertThat(result.response!!.students)
.map<String> { it.gradeClassNumber }
.contains("3417", "3517")
}
테스트 프레임워크는 BDD-Mockito
를 이용하였습니다.
겉보기에는 컨트롤러를 테스트하는 코드로 보이지만 눈에 띄는 코드가 있습니다.
andDo
메소드를 통해 document
를 생성하는 코드입니다.
여기서는 위에서 말했던 것처럼 Request
와 Response
를 검증하는 역할을 합니다.
첫 번째 인자로는 API
의 이름을 등록하고,
두, 세 번째 인자로는 Request
와 Response
에 대한 설정을 등록하는데
여기서는 나중에 테스트 코드를 빌드하여 생성되는 asciidoc
에서
Request
와 Response
를 예쁘게 찍기 위한 설정을 해두었습니다.
제일 중요한 건 마지막 인자입니다.
여기서 Response
를 검증하기 위해서는 responseFields()
메소드를,
Request
를 검증하기 위해서는 requestFields()
메소드를 사용합니다.
다른 내용은 한 눈에 봐도 무슨 뜻인지 유추하기 쉽습니다.
이렇게 도큐먼트를 생성한 뒤에는 원래 테스트 하던 것처럼
verify
해주고, 응답 assertion
하시면 됩니다.