基于Spock与Spring REST Docs生成AsciiDoc接口文档求助
修正后的完整可运行示例
1. 调整build.gradle配置
修正依赖作用域,添加Spock Spring支持,完善Asciidoctor配置:
plugins { id 'org.springframework.boot' version '2.7.5' id 'io.spring.dependency-management' version '1.0.15.RELEASE' id 'groovy' id "org.asciidoctor.convert" version "1.5.8.1" } group = 'co.example' version = '0.0.1-SNAPSHOT' sourceCompatibility = '17' repositories { mavenCentral() } ext { snippetsDir = file('build/generated-snippets') } dependencies { // Spring Boot Web核心依赖 implementation 'org.springframework.boot:spring-boot-starter-web' // Spock测试框架依赖 testImplementation 'org.spockframework:spock-core:2.0-groovy-3.0' testImplementation 'org.spockframework:spock-spring:2.0-groovy-3.0' testImplementation 'org.springframework.boot:spring-boot-starter-test' // Spring REST Docs依赖(仅测试阶段使用,必须用testImplementation) testImplementation 'org.springframework.restdocs:spring-restdocs-restassured:2.0.5.RELEASE' testImplementation 'org.springframework.restdocs:spring-restdocs-core:2.0.5.RELEASE' testImplementation 'org.springframework.restdocs:spring-restdocs-asciidoctor:2.0.5.RELEASE' } test { outputs.dir snippetsDir // 启用JUnit 4兼容模式,适配RestDocumentationRule useJUnitPlatform() } asciidoctor { inputs.dir snippetsDir dependsOn test // HTML文档输出目录 outputs.dir file('build/asciidoc') }
2. 完善Spock测试类(LeadControllerSpec)
添加Spring上下文配置、端口绑定和文档生成逻辑:
import groovy.json.JsonBuilder import org.junit.Rule import org.springframework.boot.test.context.SpringBootTest import org.springframework.boot.web.server.LocalServerPort import org.springframework.http.MediaType import org.springframework.restdocs.RestDocumentationRule import org.springframework.restdocs.payload.JsonFieldType import org.springframework.restdocs.restassured.RestAssuredRestDocumentation import org.springframework.restdocs.restassured.document import org.springframework.restdocs.payload.fieldWithPath import org.springframework.restdocs.preprocess.Preprocessors import io.restassured.RestAssured import io.restassured.builder.RequestSpecBuilder import io.restassured.specification.RequestSpecification import spock.lang.Specification @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) class LeadControllerSpec extends Specification { @LocalServerPort int localServerPort // 指定snippets输出路径,与build.gradle配置一致 @Rule RestDocumentationRule restDocumentation = new RestDocumentationRule("build/generated-snippets") RequestSpecification documentationSpec void setup() { // 绑定Spring Boot随机端口 RestAssured.port = localServerPort this.documentationSpec = new RequestSpecBuilder() .addFilter(RestAssuredRestDocumentation.documentationConfiguration(restDocumentation) .operationPreprocessors() .withRequestDefaults( Preprocessors.modifyUris().host('api.example.com').removePort(), Preprocessors.prettyPrint()) .withResponseDefaults(Preprocessors.prettyPrint())) .build() } def "test createLead endpoint"() { given: def requestBody = new JsonBuilder([ firstName: "John", lastName: "Doe", mobileNumber: "1234567890", emailId: "john@example.com", pincode: "12345", cardScheme: "SchemeA" ]).toString() when: def response = RestAssured.given(this.documentationSpec) .accept(MediaType.APPLICATION_JSON_VALUE) .contentType(MediaType.APPLICATION_JSON_VALUE) .body(requestBody) // 生成接口文档片段 .filter(document("create-lead", requestFields( fieldWithPath("firstName").type(JsonFieldType.STRING).description("联系人名字"), fieldWithPath("lastName").type(JsonFieldType.STRING).description("联系人姓氏"), fieldWithPath("mobileNumber").type(JsonFieldType.STRING).description("手机号码"), fieldWithPath("emailId").type(JsonFieldType.STRING).description("邮箱地址"), fieldWithPath("pincode").type(JsonFieldType.STRING).description("邮政编码"), fieldWithPath("cardScheme").type(JsonFieldType.STRING).description("卡组织类型") ), responseFields( fieldWithPath("id").type(JsonFieldType.NUMBER).description("生成的Lead ID"), fieldWithPath("status").type(JsonFieldType.STRING).description("请求状态"), fieldWithPath("message").type(JsonFieldType.STRING).description("提示信息") ) )) .when() .post("/api/v1/lead/create") then: response.statusCode == 200 } }
3. 创建AsciiDoc模板文件
在src/docs/asciidoc目录下创建index.adoc,整合自动生成的文档片段:
= Lead API 接口文档 :toc: left :toclevels: 3 == 创建Lead接口 === 请求示例 include::{snippets}/create-lead/http-request.adoc[] === 请求参数说明 include::{snippets}/create-lead/request-fields.adoc[] === 响应示例 include::{snippets}/create-lead/http-response.adoc[] === 响应参数说明 include::{snippets}/create-lead/response-fields.adoc[]
4. 生成完整文档
执行Gradle命令生成HTML文档:
./gradlew asciidoctor
生成的HTML文档路径为build/asciidoc/html5/index.html,直接打开即可查看格式化后的接口文档。
关键修正说明
- 依赖作用域:Spring REST Docs依赖必须设置为
testImplementation,仅在测试阶段生效 - 路径一致性:
RestDocumentationRule指定的路径必须与build.gradle中snippetsDir完全一致,确保片段生成到正确位置 - Spring上下文:通过
@SpringBootTest启用Spring容器,@LocalServerPort绑定随机端口避免冲突 - 文档生成逻辑:通过
.filter(document(...))明确指定要记录的请求/响应字段,确保接口细节被完整记录
内容的提问来源于stack exchange,提问作者vamsi
相关产品推荐
相关产品推荐

