[Spring REST API #10] Spring REST Docs 개념 및 적용
- 📚 Spring/Spring REST
- 2020. 8. 5. 00:42
| Spring REST Docs
-
Spring REST Docs는 REST API 에 대한 정보를 제공하는 Docs를 생성할 수 있는 Spring에서 제공하는 툴 이다.
-
Spring MVC Test 코드 작성 시 추가적으로 Docs를 생성하는 코드를 첨가하여 생성할 수 있다.
-
REST Docs 는 REST 아키텍처의 self-descriptive 규약을 지키기 위해 REST API의 리소스 및 API 명세 그리고 요청과 응답 데이터의 설명까지 포함된 문서를 만들 수 있게 해준다.
참고 URL : https://docs.spring.io/spring-restdocs/docs/2.0.4.RELEASE/reference/html5/
의존성 추가
<dependency>
<groupId>org.springframework.restdocs</groupId>
<artifactId>spring-restdocs-mockmvc</artifactId>
<scope>test</scope>
</dependency>
소스
package org.kyhslam.rest.common;
import org.springframework.boot.test.autoconfigure.restdocs.RestDocsMockMvcConfigurationCustomizer;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.restdocs.mockmvc.MockMvcRestDocumentationConfigurer;
import org.springframework.restdocs.operation.preprocess.Preprocessors;
@TestConfiguration
public class RestDocsConfiguration {
@Bean
public RestDocsMockMvcConfigurationCustomizer restDocsMockMvcConfigurationCustomizer(){
return new RestDocsMockMvcConfigurationCustomizer() {
@Override
public void customize(MockMvcRestDocumentationConfigurer configurer) {
configurer.operationPreprocessors()
.withRequestDefaults(Preprocessors.prettyPrint())
.withResponseDefaults(Preprocessors.prettyPrint());
}
};
}
}
package org.kyhslam.rest;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.hamcrest.Matchers;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.kyhslam.rest.common.RestDocsConfiguration;
import org.kyhslam.rest.common.TestDescription;
import org.mockito.Mockito;
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.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.annotation.Import;
import org.springframework.hateoas.MediaTypes;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.restdocs.mockmvc.MockMvcRestDocumentation;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import java.time.LocalDateTime;
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
@AutoConfigureRestDocs
@Import(RestDocsConfiguration.class)
public class EventControllerTests {
@Autowired
MockMvc mockMvc;
@Autowired
ObjectMapper objectMapper;
@Test
@TestDescription("정상적으로 이벤트를 생성하는 테스트")
public void createEvent() throws Exception {
Event event = Event.builder()
.name("Spring")
.description("REST API Development")
.beginEnrollmentDateTime(LocalDateTime.of(2018,11,23,14,21))
.closeEnrollmentDateTime(LocalDateTime.of(2018,11,23,14,21))
.beginEventDateTime(LocalDateTime.of(2018,11,25,14,21))
.endEventDateTime(LocalDateTime.of(2018,11,26,14,21))
.basePrice(100)
.maxPrice(200)
.limitOfEnrollment(100)
.location("강남역 d2 팩토리")
.build();
mockMvc.perform(MockMvcRequestBuilders.post("/api/events/")
.contentType(MediaType.APPLICATION_JSON_UTF8)
.accept(MediaTypes.HAL_JSON)
.content(objectMapper.writeValueAsString(event)))
.andDo(MockMvcResultHandlers.print())
.andExpect(MockMvcResultMatchers.status().isCreated())
.andExpect(MockMvcResultMatchers.jsonPath("id").exists())
.andExpect(MockMvcResultMatchers.header().exists(HttpHeaders.LOCATION))
.andExpect(MockMvcResultMatchers.header().string(HttpHeaders.CONTENT_TYPE,MediaTypes.HAL_JSON_UTF8_VALUE))
.andExpect(MockMvcResultMatchers.jsonPath("free").value(false))
.andExpect(MockMvcResultMatchers.jsonPath("offline").value(true))
.andExpect(MockMvcResultMatchers.jsonPath("eventStatus").value(EventStatus.DRAFT.name()))
.andExpect(MockMvcResultMatchers.jsonPath("_links.self").exists())
.andExpect(MockMvcResultMatchers.jsonPath("_links.query-events").exists())
.andExpect(MockMvcResultMatchers.jsonPath("_links.update-event").exists())
.andDo(MockMvcRestDocumentation.document("create-event"))
;
}
}
테스트를 실행하면 아래와 같이 폴더와 파일이 생성 된다.
결과
[source,bash]
----
$ curl 'http://localhost:8080/api/events/' -i -X POST \
-H 'Content-Type: application/json;charset=UTF-8' \
-H 'Accept: application/hal+json' \
-d '{
"id" : null,
"name" : "Spring",
"description" : "REST API Development",
"beginEnrollmentDateTime" : "2018-11-23T14:21:00",
"closeEnrollmentDateTime" : "2018-11-23T14:21:00",
"beginEventDateTime" : "2018-11-25T14:21:00",
"endEventDateTime" : "2018-11-26T14:21:00",
"location" : "강남역 d2 팩토리",
"basePrice" : 100,
"maxPrice" : 200,
"limitOfEnrollment" : 100,
"offline" : false,
"free" : false,
"eventStatus" : null
}'
----
'📚 Spring > Spring REST' 카테고리의 다른 글
RestAPI Document를 위한 Swagger (0) | 2021.06.29 |
---|---|
[Spring REST API #9] Spring HATEOAS 개념 및 적용 (0) | 2020.08.04 |
[Spring REST API #8] REST API 비즈니스 로직 적용 및 JunitParam을 이용한 테스트 (0) | 2020.08.03 |
[Spring REST API #7] Bad Request 에 대한 본문 메세지 (0) | 2020.07.31 |
[Spring REST API #6] Bad Request (도메인 Validator를 통한 처리) (0) | 2020.07.31 |