본문 바로가기

Spring

Spring Restdocs

728x90

(1) 버전

Java 17

Springboot 3.1.5

Spring 6.0.13

restdocs 3.0.0

Junit5

Gradle 8.4

(2) build.gradle

plugins {
    id 'org.asciidoctor.jvm.convert' version '3.3.2' // (1)
}

configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
    asciidoctorExt // (2)
}

dependencies {
    asciidoctorExt 'org.springframework.restdocs:spring-restdocs-asciidoctor' // (3)
    testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc'
}

ext {
    set('snippetsDir', file("build/generated-snippets")) //(4)
}

tasks.named('test') {
    outputs.dir snippetsDir // (5)
    useJUnitPlatform()
}

asciidoctor {
    configurations 'asciidoctorExt' // (6)
    baseDirFollowsSourceFile() // (7)
    inputs.dir snippetsDir // (8)
    dependsOn test // (9)
}

asciidoctor.doFirst {
    delete file('src/main/resources/static/docs')  // (10)
}

task createDocument(type: Copy){ // (11)
    dependsOn asciidoctor // (12)
    from file("build/docs/asciidoc")
    into file("src/main/resources/static")
}

bootJar {
    dependsOn createDocument // (13)
    from("${asciidoctor.outputDir}"){
        into 'static/docs'
    }
}

 

(1) Asciidoctor 파일을 변환하고 build 디렉토리에 복사하기 위해 사용하는 플러그인

 

(2)AsciidoctorExt를  Configuration에 지정한다.

 

(3).adoc파일에서 사용할 snippets 속성이 자동으로 build/generated-snipets를 가르키도록 해준다.

 

(4)snippets 파일이 저장될 경로를 snippetsDir로 지정한다.

 

(5)output 디렉토리를 snippetsDir로 지정한다.

 

(6)Assciidoctor에서 asciidoctorExt를 Configuration으로  사용한다.

 

(7).adoc파일에서는 다른 .adoc파일을 include하여 사용할 수 있는데 그럴 경우 동일하게 baseDir로 설정해준다.

 

(8)input 디렉토리를 snippetsDir로 지정한다.

 

(9)Gradle build시 test->asciidoctor순으로 진행한다.

 

(10)asciidoctor가 실행될 때  해당된 경로에 있는  이 전의 html을 파일을 지워준다.

 

(11)type이 copy인 실행 task를 정의하고 from에 위치한 파일을 into로 복사한다.

 

(12) Gradle build시 asciidoctor -> createDocument순으로 진행한다.

 

(13) Gradle build시 createDocument -> bootjar순으로 진행한다.

 

(14)Gradle build시 asciidoctor.outputDir에 Html파일이 생기고 이것을 jar안에 /resources/static안에 복사한다.

 

(3) RestdocsConfiguration

@TestConfiguration
public class RestDocsConfiguration {

    @Bean
    public RestDocumentationResultHandler write() {
        return MockMvcRestDocumentation.document(
                "{class-name}/{method-name}", // (1)  디렉토리 경로명
                Preprocessors.preprocessRequest(Preprocessors.prettyPrint()), //(2)
                Preprocessors.preprocessResponse(Preprocessors.prettyPrint()) // (2)
        );
    }
}

 

(1) build/generated-spinppets에 저장될 디렉토리 경로명을 설정한다.

 

(2) Preprocessors.prettyPrint()함수를 통해 snippets이 보기 쉽게 출력된다.

 

(4)ExampleController

@RestController
public class ExampleController {

    @GetMapping("/example")
    public ResponseEntity<ResponseDto> example(@RequestBody RequestDto requestDto){
        
        ResponseDto result = new ResponseDto(1L, requestDto.getName());

        return new ResponseEntity<>(result, HttpStatus.OK);
    }

}

 

requestDto에서 name을 받아 id값을 포함하여 responseDto로 응답하는 간단한 컨트롤러이다.

 

(5)MockMvcTest

(1) 기본 설정

@WebMvcTest(ExampleController.class) // (1)
@Import(RestDocsConfiguration.class) //(2)
@ExtendWith(RestDocumentationExtension.class) //(3)
public class SpringRestdocsTests {

    @Autowired
    private MockMvc mockMvc;

    @Autowired
    private RestDocumentationResultHandler restDocs;

    @Autowired
    private ObjectMapper objectMapper;

    @BeforeEach
    void setUp(
    WebApplicationContext webApplicationContext, 
    RestDocumentationContextProvider restDocumentation){
        this.mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext)
                .apply(documentationConfiguration(restDocumentation)) // (4)
                .alwaysDo(MockMvcResultHandlers.print())
                .build();
    }
    ...
}

 

(1) ExampleController만 test하기위해서 선언한다.

 

(2)위에서 설정한 RestDocsConfiguration을 import해준다.

 

(3)Junit5에서 Restdocs를 사용하기 위해 RestDocumentation Extension을 적용한다.

 

(4) MockMvcRestDocumentationConfigurer를 이용하여 restDocumentation의 인스턴스를 가져온다.

(2) restdocs test

@Test
    void exampleTest_document() throws Exception {
        //given
        RequestDto request = new RequestDto("name");


        //when,then
        mockMvc.perform(get("/example")
                        .contentType(MediaType.APPLICATION_JSON)
                        .content(objectMapper.writeValueAsString(request)))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.id").value(1L))
                .andExpect(jsonPath("$.name").value("name"))
                .andDo(restDocs); // description Type 불가능
    }

 

mockMvc테스의 .andDo 메소드에 restdocs를 넣으면 테스트가 통과한후 빌드를 하면 자동으로 build/generated-spnippets에 .adoc파일이 만들어집니다.

(3) 만들어진 adoc 파일

만들어진 adoc파일

 

 

RestdocsConfiguration에서 설정해주었던 디렉토리 경로명으로 만들어진 것을 볼 수 있습니다.

 

(6) adoc 소스파일 경로

 

Spring restdocs의 Doc를 보면 adoc 소스파일을 만들어야 html파일 생성된다고 명시되어 있습니다.

src/docs/asciidoc에 소스파일을 만들면 됩니다.

 

(7) adoc 소스파일

1. example_document.adoc

== 예시

=== 테스트
operation::spring-restdocs-tests/example-test_document[snippets='http-request,http-response']

 

2.index.adoc

:doctype: book
:source-highlighter: highlightjs
:toc: left
:toclevels: 2
:seclinks:

include::example_document.adoc[]

 

adoc 문법을 이용하여 adoc 소스파일을 생성합니다.

 

(8) 만들어진 html 파일

 

(9) 복사된 html 파일

 

(10) 결과 화면

(11) 참고 자료

1.Spring Rest Docs Documentation

https://docs.spring.io/spring-restdocs/docs/current/reference/htmlsingle/#introduction

 

Spring REST Docs

Document RESTful services by combining hand-written documentation with auto-generated snippets produced with Spring MVC Test or WebTestClient.

docs.spring.io

 

2.Adoc 문법 자료

https://narusas.github.io/2018/03/21/Asciidoc-basic.html

 

Asciidoc 기본 사용법

Asciidoc의 기본 문법을 설명한다

narusas.github.io

 

728x90

'Spring' 카테고리의 다른 글

MDC 및 로그레벨에 따른 로그파일 분리  (1) 2023.11.14
Pinpoint Cloud  (0) 2023.11.13
그라파나 설치 및 사용법  (0) 2023.11.07
프로메테우스 설치 및 사용법  (1) 2023.11.07
Actuator  (0) 2023.11.03