kotlin SpringBoot REST Docs 설정

공부는 혼자하는 거·2022년 9월 19일
0

Spring Tip

목록 보기
28/52

import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
    id("org.springframework.boot") version "2.7.1"
    id("io.spring.dependency-management") version "1.0.11.RELEASE"
    //id("org.asciidoctor.convert") version "1.5.8"
    id("org.asciidoctor.jvm.convert") version "3.3.2" //1

    kotlin("jvm") version "1.6.21"
    kotlin("plugin.spring") version "1.6.21"
    kotlin("plugin.jpa") version "1.6.21"
}

val asciidoctorExt by configurations.creating  // 2


.... 생략


var snippetsDir = file("build/generated-snippets") //3


dependencies {


// https://mvnrepository.com/artifact/org.springframework.restdocs/spring-restdocs-asciidoctor
    asciidoctorExt("org.springframework.restdocs:spring-restdocs-asciidoctor")      implementation("org.springframework.boot:spring-boot-starter-web")

    implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.13.3")
    implementation("com.fasterxml.jackson.datatype:jackson-datatype-hibernate5:2.13.3")
    implementation("org.jetbrains.kotlin:kotlin-reflect")
    implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

    ... 생략
    
     testImplementation("org.springframework.boot:spring-boot-starter-test"){
        exclude(group = "org.junit.vintage", module = "junit-vintage-engine")
    }
    testImplementation("org.springframework.restdocs:spring-restdocs-mockmvc")
    testImplementation("org.springframework.security:spring-security-test")
    implementation("it.ozimov:embedded-redis:0.7.3") { exclude(group = "org.slf4j", module = "slf4j-simple") }

}



tasks.withType<KotlinCompile> {
    kotlinOptions {
        freeCompilerArgs = listOf("-Xjsr305=strict")
        jvmTarget = "11"
    }
}

tasks.withType<Test> {
    useJUnitPlatform()
}

tasks.test {
    outputs.dir(snippetsDir)
}


tasks.asciidoctor {
    //val test by tasks
    dependsOn(tasks.test)
    configurations("asciidoctorExt")
    baseDirFollowsSourceFile()  
    inputs.dir(snippetsDir)
}

tasks.register("copyDocument", Copy::class) { 
    dependsOn(tasks.asciidoctor)
    from(file("build/docs/asciidoc/index.html"))
    into(file("src/main/resources/static/docs"))
}

tasks.build { 
    dependsOn(tasks.getByName("copyDocument"))
}

tasks.bootJar { 
    dependsOn(tasks.getByName("copyDocument"))
}

tasks.jar {
    enabled = false
}

Restdoc Test ConfigTemplateClass


@Configuration
class RestDocsConfiguration {
    @Bean
    fun write(): RestDocumentationResultHandler {
        return MockMvcRestDocumentation.document(
            "{class-name}/{method-name}",
            Preprocessors.preprocessRequest(Preprocessors.prettyPrint()),
            Preprocessors.preprocessResponse(Preprocessors.prettyPrint())
        )
    }
}

@SpringBootTest(
    properties = [""" spring.config.location=classpath:/application.yml,classpath:/aws.yml  """
    ,"spring.profiles.active=test"]
)
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@TestConstructor(autowireMode = TestConstructor.AutowireMode.ALL)
class SpringTestSupport {

    @Suppress("SpringJavaInjectionPointsAutowiringInspection")
    @Autowired
    private lateinit var entityManager: EntityManager

//    protected val query: JPAQueryFactory by lazy { JPAQueryFactory(entityManager) }

    protected fun <T> save(entity: T): T {
        entityManager.persist(entity)
        flushAndClearPersistentContext()
        return entity
    }

    protected fun <T> saveAll(entities: Iterable<T>): Iterable<T> {
        for (entity in entities) {
            entityManager.persist(entity)
        }
        flushAndClearPersistentContext()
        return entities
    }

    private fun flushAndClearPersistentContext() {
        entityManager.flush()
        entityManager.clear()
    }
}



@AutoConfigureMockMvc
@Import(RestDocsConfiguration::class)
@ExtendWith(RestDocumentationExtension::class)
class SpringWebTestSupport : SpringTestSupport() {

    @Autowired
    protected lateinit var objectMapper: ObjectMapper

    @Autowired
    protected lateinit var restdocs: RestDocsConfiguration

    @Suppress("SpringJavaInjectionPointsAutowiringInspection")
    @Autowired
    protected lateinit var mockMvc: MockMvc

    @Autowired
    protected lateinit var write: RestDocumentationResultHandler

    @Autowired
    protected lateinit var resourceLoader: ResourceLoader

    protected val classpath = "classpath:"


    protected val apiVersion = "/v1"


    @BeforeEach
    fun setUp(context: WebApplicationContext, provider: RestDocumentationContextProvider) {
        this.mockMvc = MockMvcBuilders.webAppContextSetup(context)
            .apply<DefaultMockMvcBuilder>(MockMvcRestDocumentation.documentationConfiguration(provider))
            .addFilters<DefaultMockMvcBuilder>(CharacterEncodingFilter("UTF-8", true))
            .alwaysDo<DefaultMockMvcBuilder>(MockMvcResultHandlers.print())
            .alwaysDo<DefaultMockMvcBuilder>(restdocs.write())
            .build()
    }
}

Test

@Transactional
class MemberApiTest : SpringWebTestSupport() {

 	@Test
    @DisplayName("find members")
    fun getMembersTest() {

        mockMvc.perform(
            MockMvcRequestBuilders.get("${super.apiVersion}/members")
                .accept(MediaType.APPLICATION_JSON)
        )
            .andDo(MockMvcResultHandlers.print())
            .andExpect(MockMvcResultMatchers.status().isOk)
            .andDo(MockMvcRestDocumentation.document("get-members"))
    }

}

ADOC

ifndef::snippets[]
:snippets: ./build/generated-snippets/클래스이름

endif::[]

# API 문서


== 회원목록조회

=== 요청 파라미터

include::{snippets}/get-members/request-parameters.adoc[]

profile
시간대비효율

0개의 댓글