Spring Rest Docs
Controller의 슬라이스 테스트를 통해 테스트가 통과 되어야지만 API문서가 생성됨
build.gradle 설정
plugins {
...
...
id "org.asciidoctor.jvm.convert" version "3.3.2"
}
ext {
set('snippetsDir', file("build/generated-snippets"))
}
configurations {
asciidoctorExtensions
}
dependencies {
testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc'
asciidoctorExtensions 'org.springframework.restdocs:spring-restdocs-asciidoctor'
...
...
}
tasks.named('test') {
outputs.dir snippetsDir
useJUnitPlatform()
}
tasks.named('asciidoctor') {
configurations "asciidoctorExtensions"
inputs.dir snippetsDir
dependsOn test
}
task copyDocument(type: Copy) {
dependsOn asciidoctor
from file("${asciidoctor.outputDir}")
into file("src/main/resources/static/docs")
}
build {
dependsOn copyDocument
}
bootJar {
dependsOn copyDocument
from ("${asciidoctor.outputDir}") {
into 'static/docs'
}
}
MemberControllerRestDocsTest
@WebMvcTest(MemberController.class) // Controller 테스트를 위한 전용 애너테이션
@MockBean(JpaMetamodelMappingContext.class) // JPA 빈들을 Moc 객체로 주입
@AutoConfigureRestDocs // spring Rest Docs 자동구성을 위한 애너테이션
public class MemberControllerRestDocsTest {
@Autowired
private MockMvc mockMvc; // MockMvc객체 주입
@MockBean
// 테스트 대상 Controller 클래스가 의존하는 객체를 Mock Bean 객체로 주입 받기
@Test
public void postMemberTest() throws Exception {
// given
// 테스트 데이터
// Mock 객체를 이용한 Stubbing
// when
ResultActions actions =
mockMvc.perform(
// request 전송
);
// then
actions
.andExpect(status().isCreated())
.andExpect(header().string("Location", is(startsWith("/v11/members/"))))
.andDo(document( // API 문서 생성
"post-member", // API문서 스니핏 식별자 역할
getRequestPreProcessor(), // request 영역 전처리
getResponsePreProcessor(), // response 영역 전처리
requestFields( // request body에 포함된 데이터 표현
List.of(
fieldWithPath("email").type(JsonFieldType.STRING).description("이메일"), // JSON 프로퍼티 값이 문자열
fieldWithPath("name").type(JsonFieldType.STRING).description("이름"),
fieldWithPath("phone").type(JsonFieldType.STRING).description("휴대폰 번호")
)
),
responseHeaders( // response header 표현
headerWithName(HttpHeaders.LOCATION).description("Location header. 등록된 리소스의 URI")
)
));
}
}