๐Ÿ“‹ Kotlin์œผ๋กœ Spring Rest Docs ์‚ฝ์งˆํ•˜๊ธฐ (feat. ์ œ์ž‘ ๊ทผ๋กœ)


Spring Rest Docs ์„ค์ • - build.gradle.kts

ํ”Œ๋Ÿฌ๊ทธ์ธ ์ถ”๊ฐ€

plugins{
	// ...
	id("org.asciidoctor.convert") version "1.5.9.2"
}

asciidoctor, Spring Rest Docs ์˜์กด์„ฑ ์ถ”๊ฐ€

asciidoctor("org.springframework.restdocs:spring-restdocs-asciidoctor:2.0.5.RELEASE")
testImplementation("org.springframework.restdocs:spring-restdocs-mockmvc:2.0.5.RELEASE")

snippets ์ €์žฅ ๊ฒฝ๋กœ ์ง€์ •

val snippetsDir by extra { file("build/generated-snippets") }

task ์ถ”๊ฐ€

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

    asciidoctor {
        inputs.dir(snippetsDir)
        dependsOn(test)
    }

    bootJar {
        dependsOn(asciidoctor)
        from("$snippetsDir/html5") {
            into("static/docs")
        }
    }
}

โž• tasks - ์‚ฌ์šฉ์ž ์ •์˜ task๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Œ

ํ…Œ์Šคํฌ๋ž€?
  • gradle์€ ๋ช…๋ น์—์˜ํ•ด ํ…Œ์Šคํฌ(Task)๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” ํ”„๋กœ๊ทธ๋žจ
  • gradle compileJava , gradle run ๋“ฑ ๋ช…๋ น์–ด๋ฅผ ํ†ตํ•ด ์‹คํ–‰ํ•˜๋Š” ๊ฒƒ๋“ค์ด ๋ชจ๋‘ ํ…Œ์Šคํฌ
  • Gradle ํ”„๋กœ์ ํŠธ์˜ ์ž‘์—…๋‹จ์œ„
  • Task๋Š” ๋…๋ฆฝ์ ์ธ ์•ก์…˜์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๊ณ , ๋‹ค๋ฅธ Task์— ๋Œ€ํ•œ ์˜์กด์„ฑ์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Œ

Spring Rest Docs ์‚ฝ์งˆ ๊ธฐ๋ก

  • build.gradle.kts ์„ค์ •์„ ๋๋ƒ„
  • generated-snippets ํด๋”๋Š” ๋งŒ๋“ค์–ด ์ง€์ง€๋งŒ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ๋Œ๋ ค๋„ ์Šค๋‹™ํŽซ์ด ๋งŒ๋“ค์–ด์ง€์ง€ ์•Š๋Š” ๋ฌธ์ œ ๋ฐœ์ƒ
  • build.gradle.kts ๋ฌธ์ œ์ผ์ค„ ์•Œ์•˜์œผ๋‚˜ ์•„๋‹ˆ์—ˆ๋‹ค

  • ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๊ฐ€ dsl ๋กœ ๋˜์–ด ์žˆ์Œ

  • https://github.com/spring-projects/spring-restdocs/issues/677
  • dsl ์ผ ๊ฒฝ์šฐ handle()์„ ํ†ตํ•ด document()์‹คํ–‰ํ•ด์•ผํ•จ

mockMvc ์„ค์ •

  • @AutoConfigureRestDocs ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด @AutoConfigureMockMvc ๋ฅผ ํ†ตํ•ด ์ˆ˜๋™ ์„ค์ •ํ•ด์ฃผ๊ณ  ์‹ถ์—ˆ์œผ๋‚˜
  • @AutoConfigureMockMvc ๋ฅผ ํ•ด์ฃผ๋ฉด utf-8 ์„ค์ •์„ ํ•  ์ˆ˜ ์—†๋Š” ์˜ค๋ฅ˜ ๋ฐœ์ƒ
  • ๋•Œ๋ฌธ๊ธฐ์กด ์ฝ”๋“œ๋Š” mockMvc๋ฅผ ์ˆ˜๋™ ์„ค์ •ํ•ด์ฃผ๊ณ  ์žˆ์—ˆ์Œ
  • ์ด๋Ÿฌ๋ฉด @AutoConfigureRestDocs ์ด ๋จนํžˆ์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์•„๋ž˜์™€ ๊ฐ™์€ ์˜ค๋ฅ˜ ๋ฐœ์ƒ

  • ๋‹ค์Œ ์„ค์ •์„ ํ†ตํ•ด RestDocs ๊ด€๋ จ ์„ค์ •๋„ mockmvc์— ์ถ”๊ฐ€

์–ด๋…ธํ…Œ์ด์…˜ ์ถ”๊ฐ€

@Import(RestDocsConfiguration::class)
@ExtendWith(RestDocumentationExtension::class, SpringExtension::class)

setUp

@BeforeEach
internal fun setUp(
    webApplicationContext: WebApplicationContext,
    restDocumentationContextProvider: RestDocumentationContextProvider
) {
    mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext)
        .addFilter<DefaultMockMvcBuilder>(CharacterEncodingFilter("UTF-8", true))
        .alwaysDo<DefaultMockMvcBuilder>(MockMvcResultHandlers.print())
        .apply<DefaultMockMvcBuilder>(
            MockMvcRestDocumentation.documentationConfiguration(
                restDocumentationContextProvider
            )
        )
        .build()
}

์ฐธ๊ณ ์ž๋ฃŒ