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[]