From e91e5b0c9da71816d8f09d04008ce4cb0906ce7c Mon Sep 17 00:00:00 2001 From: LJW25 Date: Wed, 12 Jul 2023 23:37:56 +0900 Subject: [PATCH 1/7] =?UTF-8?q?chore:=20RestDocs=20=EB=9D=BC=EC=9D=B4?= =?UTF-8?q?=EB=B8=8C=EB=9F=AC=EB=A6=AC=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/build.gradle | 58 +++++++++++++++++++++++++++++++------------- 1 file changed, 41 insertions(+), 17 deletions(-) diff --git a/backend/build.gradle b/backend/build.gradle index a1841323b..0d8478273 100644 --- a/backend/build.gradle +++ b/backend/build.gradle @@ -1,38 +1,62 @@ plugins { - id 'java' - id 'org.springframework.boot' version '3.1.1' - id 'io.spring.dependency-management' version '1.1.0' + id 'java' + id 'org.springframework.boot' version '3.1.1' + id 'io.spring.dependency-management' version '1.1.0' + id "org.asciidoctor.jvm.convert" version "3.3.2" } group = 'hanglog' version = '0.0.1-SNAPSHOT' java { - sourceCompatibility = '17' + sourceCompatibility = '17' } configurations { - compileOnly { - extendsFrom annotationProcessor - } + asciidoctorExt + compileOnly { + extendsFrom annotationProcessor + } } repositories { - mavenCentral() + mavenCentral() } dependencies { - implementation 'org.springframework.boot:spring-boot-starter-data-jpa' - implementation 'org.springframework.boot:spring-boot-starter-validation' - implementation 'org.springframework.boot:spring-boot-starter-web' - implementation 'com.github.gavlyukovskiy:p6spy-spring-boot-starter:1.9.0' + implementation 'org.springframework.boot:spring-boot-starter-data-jpa' + implementation 'org.springframework.boot:spring-boot-starter-validation' + implementation 'org.springframework.boot:spring-boot-starter-web' + implementation 'com.github.gavlyukovskiy:p6spy-spring-boot-starter:1.9.0' - compileOnly 'org.projectlombok:lombok' - runtimeOnly 'com.h2database:h2' - annotationProcessor 'org.projectlombok:lombok' - testImplementation 'org.springframework.boot:spring-boot-starter-test' + testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc' + asciidoctorExt 'org.springframework.restdocs:spring-restdocs-asciidoctor' + + compileOnly 'org.projectlombok:lombok' + runtimeOnly 'com.h2database:h2' + annotationProcessor 'org.projectlombok:lombok' + testImplementation 'org.springframework.boot:spring-boot-starter-test' } tasks.named('test') { - useJUnitPlatform() + useJUnitPlatform() +} + +asciidoctor { + dependsOn test + configurations 'asciidoctorExt' +} + +tasks.register('copyApiDocument', Copy) { + dependsOn asciidoctor + doFirst { + delete file("src/main/resources/static/docs") + } + from asciidoctor.outputDir + into file("src/main/resources/static/docs") +} + +build { + dependsOn copyApiDocument } + From 8d101355df45fcb6d737be3f919ae85597e4a409 Mon Sep 17 00:00:00 2001 From: LJW25 Date: Wed, 12 Jul 2023 23:42:51 +0900 Subject: [PATCH 2/7] =?UTF-8?q?chore:=20RestDocs=20=ED=81=B4=EB=9E=98?= =?UTF-8?q?=EC=8A=A4=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../trip/restdocs/RestDocsConfiguration.java | 32 +++++++++++++++++ .../hanglog/trip/restdocs/RestDocsTest.java | 36 +++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 backend/src/test/java/hanglog/trip/restdocs/RestDocsConfiguration.java create mode 100644 backend/src/test/java/hanglog/trip/restdocs/RestDocsTest.java diff --git a/backend/src/test/java/hanglog/trip/restdocs/RestDocsConfiguration.java b/backend/src/test/java/hanglog/trip/restdocs/RestDocsConfiguration.java new file mode 100644 index 000000000..01a04707d --- /dev/null +++ b/backend/src/test/java/hanglog/trip/restdocs/RestDocsConfiguration.java @@ -0,0 +1,32 @@ +package hanglog.trip.restdocs; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.restdocs.mockmvc.MockMvcRestDocumentation; +import org.springframework.restdocs.mockmvc.RestDocumentationResultHandler; +import org.springframework.restdocs.operation.preprocess.Preprocessors; +import org.springframework.restdocs.snippet.Attributes.Attribute; + + +@Configuration +public class RestDocsConfiguration { + + public static final Attribute field(final String key, final String value) { + return new Attribute(key, value); + } + + @Bean + public RestDocumentationResultHandler write() { + return MockMvcRestDocumentation.document( + "{class-name}/{method-name}", + Preprocessors.preprocessRequest( + Preprocessors.removeHeaders("Content-Length", "Host"), + Preprocessors.prettyPrint() + ), + Preprocessors.preprocessResponse( + Preprocessors.removeHeaders("Transfer-Encoding", "Date", "Keep-Alive", "Connection"), + Preprocessors.prettyPrint() + ) + ); + } +} diff --git a/backend/src/test/java/hanglog/trip/restdocs/RestDocsTest.java b/backend/src/test/java/hanglog/trip/restdocs/RestDocsTest.java new file mode 100644 index 000000000..16c08c58d --- /dev/null +++ b/backend/src/test/java/hanglog/trip/restdocs/RestDocsTest.java @@ -0,0 +1,36 @@ +package hanglog.trip.restdocs; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Import; +import org.springframework.restdocs.RestDocumentationContextProvider; +import org.springframework.restdocs.RestDocumentationExtension; +import org.springframework.restdocs.mockmvc.RestDocumentationResultHandler; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; +import org.springframework.web.filter.CharacterEncodingFilter; + +import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration; + +@Import(RestDocsConfiguration.class) +@ExtendWith(RestDocumentationExtension.class) +public abstract class RestDocsTest { + + @Autowired + protected RestDocumentationResultHandler restDocs; + @Autowired + protected MockMvc mockMvc; + + @BeforeEach + void setUp( + final WebApplicationContext context, + final RestDocumentationContextProvider restDocumentation) { + this.mockMvc = MockMvcBuilders.webAppContextSetup(context) + .apply(documentationConfiguration(restDocumentation)) + .alwaysDo(restDocs) + .addFilters(new CharacterEncodingFilter("UTF-8", true)) + .build(); + } +} From c5455b6562093a4b40748e9a3d394f0273fa5ed1 Mon Sep 17 00:00:00 2001 From: LJW25 Date: Wed, 12 Jul 2023 23:43:39 +0900 Subject: [PATCH 3/7] =?UTF-8?q?test:=20=EC=97=AC=ED=96=89=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=20API=20=ED=85=8C=EC=8A=A4=ED=8A=B8=EC=97=90=20RestDo?= =?UTF-8?q?cs=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../trip/presentation/TripControllerTest.java | 57 ++++++++++++------- 1 file changed, 37 insertions(+), 20 deletions(-) diff --git a/backend/src/test/java/hanglog/trip/presentation/TripControllerTest.java b/backend/src/test/java/hanglog/trip/presentation/TripControllerTest.java index 6e7aeb448..a4f7f2f36 100644 --- a/backend/src/test/java/hanglog/trip/presentation/TripControllerTest.java +++ b/backend/src/test/java/hanglog/trip/presentation/TripControllerTest.java @@ -1,39 +1,44 @@ package hanglog.trip.presentation; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.BDDMockito.given; -import static org.springframework.http.HttpHeaders.LOCATION; -import static org.springframework.http.MediaType.APPLICATION_JSON; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - import com.fasterxml.jackson.databind.ObjectMapper; import hanglog.trip.presentation.dto.request.TripRequest; +import hanglog.trip.restdocs.RestDocsConfiguration; +import hanglog.trip.restdocs.RestDocsTest; import hanglog.trip.service.TripService; -import java.time.LocalDate; -import java.util.Collections; -import java.util.List; -import java.util.regex.Matcher; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.context.annotation.Import; import org.springframework.data.jpa.mapping.JpaMetamodelMappingContext; -import org.springframework.test.web.servlet.MockMvc; +import org.springframework.restdocs.payload.JsonFieldType; + +import java.time.LocalDate; +import java.util.Collections; +import java.util.List; + +import static hanglog.trip.restdocs.RestDocsConfiguration.field; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.given; +import static org.springframework.http.HttpHeaders.LOCATION; +import static org.springframework.http.MediaType.APPLICATION_JSON; +import static org.springframework.restdocs.headers.HeaderDocumentation.headerWithName; +import static org.springframework.restdocs.headers.HeaderDocumentation.responseHeaders; +import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath; +import static org.springframework.restdocs.payload.PayloadDocumentation.requestFields; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; @WebMvcTest(TripController.class) @MockBean(JpaMetamodelMappingContext.class) -class TripControllerTest { - - @Autowired - private MockMvc mockMvc; +@AutoConfigureRestDocs +@Import(RestDocsConfiguration.class) +class TripControllerTest extends RestDocsTest { @Autowired private ObjectMapper objectMapper; - @MockBean private TripService tripService; @@ -53,7 +58,19 @@ void createTrip() throws Exception { .contentType(APPLICATION_JSON) .content(objectMapper.writeValueAsString(tripRequest))) .andExpect(status().isCreated()) - .andExpect(header().string(LOCATION, "/trips/1")); + .andExpect(header().string(LOCATION, "/trips/1")) + .andDo( + restDocs.document( + requestFields( + fieldWithPath("startDate").type(JsonFieldType.STRING).description("여행 시작 날짜").attributes(field("constraint", "yyyy-MM-dd")), + fieldWithPath("endDate").type(JsonFieldType.STRING).description("여행 종료 날짜").attributes(field("constraint", "yyyy-MM-dd")), + fieldWithPath("cityIds").type(JsonFieldType.ARRAY).description("도시 ID 목록").attributes(field("constraint", "1개 이상의 양의 정수")) + ), + responseHeaders( + headerWithName(LOCATION).description("생성된 여행 URL") + ) + ) + ); } @DisplayName("여행 시작 날짜를 입력하지 않으면 예외가 발생한다.") From f02a73ad2a61dbc8572321ce67bd0aedf822677a Mon Sep 17 00:00:00 2001 From: LJW25 Date: Wed, 12 Jul 2023 23:43:59 +0900 Subject: [PATCH 4/7] =?UTF-8?q?docs:=20RestDocs=20=ED=85=9C=ED=94=8C?= =?UTF-8?q?=EB=A6=BF=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/src/docs/asciidoc/docs.adoc | 48 +++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 backend/src/docs/asciidoc/docs.adoc diff --git a/backend/src/docs/asciidoc/docs.adoc b/backend/src/docs/asciidoc/docs.adoc new file mode 100644 index 000000000..d5418dfc5 --- /dev/null +++ b/backend/src/docs/asciidoc/docs.adoc @@ -0,0 +1,48 @@ += HanngLog +:toc: left +:source-highlighter: highlightjs +:sectlinks: + +[[overview-http-status-codes]] +=== HTTP status codes + +|=== +| 상태 코드 | 설명 + +| `200 OK` +| 성공 + +| `201 Created` +| 리소스 생성 + +| `204 NO_CONTENT` +| 성공 후 반환 값 없음 + +| `400 Bad Request` +| 잘못된 요청 + +| `401 Unauthorized` +| 비인증 상태 + +| `403 Forbidden` +| 권한 거부 + +| `404 Not Found` +| 존재하지 않는 요청 리소스 + +| `500 Internal Server Error` +| 서버 에러 +|=== + + +== 여행 API + +=== 단일 여행 생성 + +==== 요청 +include::{snippets}/trip-controller-test/create-trip/http-request.adoc[] +include::{snippets}/trip-controller-test/create-trip/request-fields.adoc[] + +==== 응답 +include::{snippets}/trip-controller-test/create-trip/http-response.adoc[] +include::{snippets}/trip-controller-test/create-trip/response-headers.adoc[] From 2038986b0698f1c34ab17994c63611325d8c904e Mon Sep 17 00:00:00 2001 From: LJW25 Date: Thu, 13 Jul 2023 00:03:17 +0900 Subject: [PATCH 5/7] =?UTF-8?q?docs:=20=EC=98=A4=ED=83=80=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/src/docs/asciidoc/docs.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/docs/asciidoc/docs.adoc b/backend/src/docs/asciidoc/docs.adoc index d5418dfc5..90702a44a 100644 --- a/backend/src/docs/asciidoc/docs.adoc +++ b/backend/src/docs/asciidoc/docs.adoc @@ -1,4 +1,4 @@ -= HanngLog += HangLog :toc: left :source-highlighter: highlightjs :sectlinks: From 458b21be795133d42b5eed4a17de6aa27b7e25dd Mon Sep 17 00:00:00 2001 From: LJW25 Date: Thu, 13 Jul 2023 10:24:35 +0900 Subject: [PATCH 6/7] =?UTF-8?q?style:=20=EC=BD=94=EB=93=9C=20=EC=8A=A4?= =?UTF-8?q?=ED=83=80=EC=9D=BC=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../trip/presentation/TripControllerTest.java | 42 ++++++++++--------- .../hanglog/trip/restdocs/RestDocsTest.java | 4 +- 2 files changed, 25 insertions(+), 21 deletions(-) diff --git a/backend/src/test/java/hanglog/trip/presentation/TripControllerTest.java b/backend/src/test/java/hanglog/trip/presentation/TripControllerTest.java index a4f7f2f36..d73d8e046 100644 --- a/backend/src/test/java/hanglog/trip/presentation/TripControllerTest.java +++ b/backend/src/test/java/hanglog/trip/presentation/TripControllerTest.java @@ -1,10 +1,27 @@ package hanglog.trip.presentation; +import static hanglog.trip.restdocs.RestDocsConfiguration.field; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.given; +import static org.springframework.http.HttpHeaders.LOCATION; +import static org.springframework.http.MediaType.APPLICATION_JSON; +import static org.springframework.restdocs.headers.HeaderDocumentation.headerWithName; +import static org.springframework.restdocs.headers.HeaderDocumentation.responseHeaders; +import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath; +import static org.springframework.restdocs.payload.PayloadDocumentation.requestFields; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + import com.fasterxml.jackson.databind.ObjectMapper; import hanglog.trip.presentation.dto.request.TripRequest; import hanglog.trip.restdocs.RestDocsConfiguration; import hanglog.trip.restdocs.RestDocsTest; import hanglog.trip.service.TripService; +import java.time.LocalDate; +import java.util.Collections; +import java.util.List; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -15,22 +32,6 @@ import org.springframework.data.jpa.mapping.JpaMetamodelMappingContext; import org.springframework.restdocs.payload.JsonFieldType; -import java.time.LocalDate; -import java.util.Collections; -import java.util.List; - -import static hanglog.trip.restdocs.RestDocsConfiguration.field; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.BDDMockito.given; -import static org.springframework.http.HttpHeaders.LOCATION; -import static org.springframework.http.MediaType.APPLICATION_JSON; -import static org.springframework.restdocs.headers.HeaderDocumentation.headerWithName; -import static org.springframework.restdocs.headers.HeaderDocumentation.responseHeaders; -import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath; -import static org.springframework.restdocs.payload.PayloadDocumentation.requestFields; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; - @WebMvcTest(TripController.class) @MockBean(JpaMetamodelMappingContext.class) @AutoConfigureRestDocs @@ -62,9 +63,12 @@ void createTrip() throws Exception { .andDo( restDocs.document( requestFields( - fieldWithPath("startDate").type(JsonFieldType.STRING).description("여행 시작 날짜").attributes(field("constraint", "yyyy-MM-dd")), - fieldWithPath("endDate").type(JsonFieldType.STRING).description("여행 종료 날짜").attributes(field("constraint", "yyyy-MM-dd")), - fieldWithPath("cityIds").type(JsonFieldType.ARRAY).description("도시 ID 목록").attributes(field("constraint", "1개 이상의 양의 정수")) + fieldWithPath("startDate").type(JsonFieldType.STRING).description("여행 시작 날짜") + .attributes(field("constraint", "yyyy-MM-dd")), + fieldWithPath("endDate").type(JsonFieldType.STRING).description("여행 종료 날짜") + .attributes(field("constraint", "yyyy-MM-dd")), + fieldWithPath("cityIds").type(JsonFieldType.ARRAY).description("도시 ID 목록") + .attributes(field("constraint", "1개 이상의 양의 정수")) ), responseHeaders( headerWithName(LOCATION).description("생성된 여행 URL") diff --git a/backend/src/test/java/hanglog/trip/restdocs/RestDocsTest.java b/backend/src/test/java/hanglog/trip/restdocs/RestDocsTest.java index 16c08c58d..78069c8ba 100644 --- a/backend/src/test/java/hanglog/trip/restdocs/RestDocsTest.java +++ b/backend/src/test/java/hanglog/trip/restdocs/RestDocsTest.java @@ -1,5 +1,7 @@ package hanglog.trip.restdocs; +import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration; + import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; @@ -12,8 +14,6 @@ import org.springframework.web.context.WebApplicationContext; import org.springframework.web.filter.CharacterEncodingFilter; -import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration; - @Import(RestDocsConfiguration.class) @ExtendWith(RestDocumentationExtension.class) public abstract class RestDocsTest { From 5f324659a4df401fcce61693df07c47cd380f22a Mon Sep 17 00:00:00 2001 From: LJW25 Date: Thu, 13 Jul 2023 10:40:02 +0900 Subject: [PATCH 7/7] =?UTF-8?q?style:=20=EC=BD=94=EB=93=9C=20=EC=8A=A4?= =?UTF-8?q?=ED=83=80=EC=9D=BC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../trip/presentation/TripControllerTest.java | 13 ++++++++++--- .../trip/restdocs/RestDocsConfiguration.java | 2 +- .../java/hanglog/trip/restdocs/RestDocsTest.java | 1 + 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/backend/src/test/java/hanglog/trip/presentation/TripControllerTest.java b/backend/src/test/java/hanglog/trip/presentation/TripControllerTest.java index d73d8e046..4a228e15e 100644 --- a/backend/src/test/java/hanglog/trip/presentation/TripControllerTest.java +++ b/backend/src/test/java/hanglog/trip/presentation/TripControllerTest.java @@ -40,6 +40,7 @@ class TripControllerTest extends RestDocsTest { @Autowired private ObjectMapper objectMapper; + @MockBean private TripService tripService; @@ -63,11 +64,17 @@ void createTrip() throws Exception { .andDo( restDocs.document( requestFields( - fieldWithPath("startDate").type(JsonFieldType.STRING).description("여행 시작 날짜") + fieldWithPath("startDate") + .type(JsonFieldType.STRING) + .description("여행 시작 날짜") .attributes(field("constraint", "yyyy-MM-dd")), - fieldWithPath("endDate").type(JsonFieldType.STRING).description("여행 종료 날짜") + fieldWithPath("endDate") + .type(JsonFieldType.STRING) + .description("여행 종료 날짜") .attributes(field("constraint", "yyyy-MM-dd")), - fieldWithPath("cityIds").type(JsonFieldType.ARRAY).description("도시 ID 목록") + fieldWithPath("cityIds") + .type(JsonFieldType.ARRAY) + .description("도시 ID 목록") .attributes(field("constraint", "1개 이상의 양의 정수")) ), responseHeaders( diff --git a/backend/src/test/java/hanglog/trip/restdocs/RestDocsConfiguration.java b/backend/src/test/java/hanglog/trip/restdocs/RestDocsConfiguration.java index 01a04707d..4568c7aab 100644 --- a/backend/src/test/java/hanglog/trip/restdocs/RestDocsConfiguration.java +++ b/backend/src/test/java/hanglog/trip/restdocs/RestDocsConfiguration.java @@ -11,7 +11,7 @@ @Configuration public class RestDocsConfiguration { - public static final Attribute field(final String key, final String value) { + public static Attribute field(final String key, final String value) { return new Attribute(key, value); } diff --git a/backend/src/test/java/hanglog/trip/restdocs/RestDocsTest.java b/backend/src/test/java/hanglog/trip/restdocs/RestDocsTest.java index 78069c8ba..021bad66f 100644 --- a/backend/src/test/java/hanglog/trip/restdocs/RestDocsTest.java +++ b/backend/src/test/java/hanglog/trip/restdocs/RestDocsTest.java @@ -20,6 +20,7 @@ public abstract class RestDocsTest { @Autowired protected RestDocumentationResultHandler restDocs; + @Autowired protected MockMvc mockMvc;