快速开始
本节介绍如何开始使用 Spring REST Docs。
示例应用程序
如果您想直接开始,这里提供了一些示例应用程序。
要求
Spring REST Docs 具有以下最低要求:
-
Java 17
-
Spring 框架 6
此外,spring-restdocs-restassured 模块需要 REST Assured 5.2。
构建配置
使用 Spring REST Docs 的第一步是配置项目的构建。
Spring HATEOAS 和 Spring Data REST 示例分别包含 build.gradle 和 pom.xml,您可以将其用作参考。
配置的关键部分在以下列表中描述:
<dependency> (1)
<groupId>org.springframework.restdocs</groupId>
<artifactId>spring-restdocs-mockmvc</artifactId>
<version>{project-version}</version>
<scope>test</scope>
</dependency>
<build>
<plugins>
<plugin> (2)
<groupId>org.asciidoctor</groupId>
<artifactId>asciidoctor-maven-plugin</artifactId>
<version>2.2.1</version>
<executions>
<execution>
<id>generate-docs</id>
<phase>prepare-package</phase> (3)
<goals>
<goal>process-asciidoc</goal>
</goals>
<configuration>
<backend>html</backend>
<doctype>book</doctype>
</configuration>
</execution>
</executions>
<dependencies>
<dependency> (4)
<groupId>org.springframework.restdocs</groupId>
<artifactId>spring-restdocs-asciidoctor</artifactId>
<version>{project-version}</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
| 1 | 在 test 作用域中添加对 spring-restdocs-mockmvc 的依赖。
如果您想使用 WebTestClient 或 REST Assured 而不是 MockMvc,请分别添加对 spring-restdocs-webtestclient 或 spring-restdocs-restassured 的依赖。 |
| 2 | 添加 Asciidoctor 插件。 |
| 3 | 使用 prepare-package 可使文档包含在软件包中。 |
| 4 | 将 spring-restdocs-asciidoctor 添加为 Asciidoctor 插件的依赖项。
这将自动配置 snippets 属性,以便在您的 .adoc 文件中指向 target/generated-snippets。
它还允许您使用 operation 块宏。 |
plugins { (1)
id "org.asciidoctor.jvm.convert" version "3.3.2"
}
configurations {
asciidoctorExt (2)
}
dependencies {
asciidoctorExt 'org.springframework.restdocs:spring-restdocs-asciidoctor:{project-version}' (3)
testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc:{project-version}' (4)
}
ext { (5)
snippetsDir = file('build/generated-snippets')
}
test { (6)
outputs.dir snippetsDir
}
asciidoctor { (7)
inputs.dir snippetsDir (8)
configurations 'asciidoctorExt' (9)
dependsOn test (10)
}
| 1 | 应用 Asciidoctor 插件。 |
| 2 | 为扩展 Asciidoctor 的依赖项声明 asciidoctorExt 配置。 |
| 3 | 在 asciidoctorExt 配置中添加对 spring-restdocs-asciidoctor 的依赖。
这将自动配置 snippets 属性,以便在您的 .adoc 文件中指向 build/generated-snippets。
它还允许您使用 operation 块宏。 |
| 4 | 在 testImplementation 配置中添加对 spring-restdocs-mockmvc 的依赖。
如果您想使用 WebTestClient 或 REST Assured 而不是 MockMvc,请分别添加对 spring-restdocs-webtestclient 或 spring-restdocs-restassured 的依赖。 |
| 5 | 配置一个 snippetsDir 属性,用于定义生成代码片段的输出位置。 |
| 6 | 让 Gradle 知道运行 test 任务会将输出写入 snippetsDir。这是 增量构建 所必需的。 |
| 7 | 配置 asciidoctor 任务。 |
| 8 | 让 Gradle 意识到运行该任务将从 snippetsDir 读取输入。这对于 增量构建 是必需的。 |
| 9 | 配置使用 asciidoctorExt 配置来支持扩展。 |
| 10 | 让该任务依赖于 test 任务,以便在生成文档之前先运行测试。 |
打包文档
您可能希望将生成的文档打包到项目的 jar 文件中——例如,以便通过 Spring Boot 将其作为静态内容提供。 为此,请配置项目的构建,使其满足以下条件:
-
文档在构建 jar 包之前生成
-
生成的文档包含在 jar 文件中
以下列表展示了如何在 Maven 和 Gradle 中实现:
<plugin> (1)
<groupId>org.asciidoctor</groupId>
<artifactId>asciidoctor-maven-plugin</artifactId>
<!-- … -->
</plugin>
<plugin> (2)
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
<id>copy-resources</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration> (3)
<outputDirectory>
${project.build.outputDirectory}/static/docs
</outputDirectory>
<resources>
<resource>
<directory>
${project.build.directory}/generated-docs
</directory>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
| 1 | Asciidoctor 插件的现有声明。 |
| 2 | 资源插件必须在 Asciidoctor 插件之后声明,因为它们绑定到相同的阶段 (prepare-package),并且资源插件必须在 Asciidoctor 插件之后运行,以确保文档在复制之前已生成。
如果您未使用 Spring Boot 及其插件管理功能,请使用适当的 <version> 来声明该插件。 |
| 3 | 将生成的文档复制到构建输出的 static/docs 目录中,之后它将被包含在 jar 文件中。 |
bootJar {
dependsOn asciidoctor (1)
from ("${asciidoctor.outputDir}") { (2)
into 'static/docs'
}
}
| 1 | 确保在构建 jar 之前已生成文档。 |
| 2 | 将生成的文档复制到 jar 的 static/docs 目录中。 |
生成文档片段
Spring REST Docs 使用 Spring MVC 的测试框架、Spring WebFlux 的WebTestClient或REST Assured向您正在文档化的服务发起请求。
随后,它会为请求及相应的响应生成文档片段。
设置您的测试
测试的具体设置方式取决于您所使用的测试框架。 Spring REST Docs 为 JUnit 5 和 JUnit 4 提供了一流的支持。 推荐使用 JUnit 5。 其他框架(如 TestNG)也受支持,但需要稍多的配置工作。
设置您的 JUnit 5 测试
使用 JUnit 5 时,生成文档片段的第一步是将 RestDocumentationExtension 应用到您的测试类。
以下示例展示了如何操作:
@ExtendWith(RestDocumentationExtension.class)
public class JUnit5ExampleTests {
在测试典型的 Spring 应用程序时,您还应应用 SpringExtension:
@ExtendWith({RestDocumentationExtension.class, SpringExtension.class})
public class JUnit5ExampleTests {
RestDocumentationExtension 会根据您的项目构建工具自动配置输出目录:
| 构建工具 | 输出目录 |
|---|---|
Maven |
|
Gradle |
|
如果您使用的是 JUnit 5.1,可以通过在测试类中将扩展注册为字段,并在创建时提供输出目录来覆盖默认设置。 以下示例展示了如何实现这一点:
public class JUnit5ExampleTests {
@RegisterExtension
final RestDocumentationExtension restDocumentation = new RestDocumentationExtension ("custom");
}
接下来,您必须提供一个 @BeforeEach 方法来配置 MockMvc、WebTestClient 或 REST Assured。
以下示例展示了如何实现:
private MockMvc mockMvc;
@BeforeEach
void setUp(WebApplicationContext webApplicationContext, RestDocumentationContextProvider restDocumentation) {
this.mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext)
.apply(documentationConfiguration(restDocumentation)) (1)
.build();
}
| 1 | MockMvc 实例是通过使用 MockMvcRestDocumentationConfigurer 进行配置的。
您可以从 org.springframework.restdocs.mockmvc.MockMvcRestDocumentation 上的静态 documentationConfiguration() 方法获取此类的实例。 |
private WebTestClient webTestClient;
@BeforeEach
void setUp(ApplicationContext applicationContext, RestDocumentationContextProvider restDocumentation) {
this.webTestClient = WebTestClient.bindToApplicationContext(applicationContext)
.configureClient()
.filter(documentationConfiguration(restDocumentation)) (1)
.build();
}
| 1 | WebTestClient 实例是通过添加一个 WebTestClientRestDocumentationConfigurer 作为 ExchangeFilterFunction 来配置的。
您可以从 org.springframework.restdocs.webtestclient.WebTestClientRestDocumentation 上的静态 documentationConfiguration() 方法获取该类的实例。 |
private RequestSpecification spec;
@BeforeEach
void setUp(RestDocumentationContextProvider restDocumentation) {
this.spec = new RequestSpecBuilder().addFilter(documentationConfiguration(restDocumentation)) (1)
.build();
}
| 1 | REST Assured 通过添加一个 RestAssuredRestDocumentationConfigurer 作为 Filter 来进行配置。
您可以从 org.springframework.restdocs.restassured 包中 RestAssuredRestDocumentation 类的静态 documentationConfiguration() 方法获取该类的实例。 |
该配置器应用了合理的默认值,并提供了用于自定义配置的 API。 请参阅 配置部分 以获取更多信息。
设置您的 JUnit 4 测试
使用 JUnit 4 时,生成文档片段的第一步是声明一个标注为 JUnit @Rule 的 public JUnitRestDocumentation 字段。
以下示例展示了如何实现这一点:
@Rule
public JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation();
默认情况下,JUnitRestDocumentation 规则会根据项目的构建工具自动配置输出目录:
| 构建工具 | 输出目录 |
|---|---|
Maven |
|
Gradle |
|
您可以在创建 JUnitRestDocumentation 实例时提供输出目录,以覆盖默认设置。
以下示例展示了如何实现:
@Rule
public JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation("custom");
接下来,您必须提供一个 @Before 方法来配置 MockMvc、WebTestClient 或 REST Assured。
以下示例展示了如何实现:
private MockMvc mockMvc;
@Autowired
private WebApplicationContext context;
@Before
public void setUp() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context)
.apply(documentationConfiguration(this.restDocumentation)) (1)
.build();
}
| 1 | MockMvc 实例是通过使用 MockMvcRestDocumentationConfigurer 进行配置的。
您可以从 org.springframework.restdocs.mockmvc.MockMvcRestDocumentation 上的静态 documentationConfiguration() 方法获取此类的实例。 |
private WebTestClient webTestClient;
@Autowired
private ApplicationContext context;
@Before
public void setUp() {
this.webTestClient = WebTestClient.bindToApplicationContext(this.context)
.configureClient()
.filter(documentationConfiguration(this.restDocumentation)) (1)
.build();
}
| 1 | WebTestClient 实例是通过添加一个 WebTestclientRestDocumentationConfigurer 作为 ExchangeFilterFunction 来配置的。
您可以从 org.springframework.restdocs.webtestclient.WebTestClientRestDocumentation 上的静态 documentationConfiguration() 方法获取该类的实例。 |
private RequestSpecification spec;
@Before
public void setUp() {
this.spec = new RequestSpecBuilder().addFilter(documentationConfiguration(this.restDocumentation)) (1)
.build();
}
| 1 | REST Assured 通过添加一个 RestAssuredRestDocumentationConfigurer 作为 Filter 来进行配置。
您可以从 org.springframework.restdocs.restassured 包中 RestAssuredRestDocumentation 类的静态 documentationConfiguration() 方法获取该类的实例。 |
该配置器应用了合理的默认值,并提供了用于自定义配置的 API。 请参阅 配置部分 以获取更多信息。
在不使用 JUnit 的情况下设置测试
当不使用 JUnit 时的配置与使用时的配置大体相似。 本节介绍主要差异。 TestNG 示例也说明了该方法。
第一个区别是,您应该使用 ManualRestDocumentation 代替 JUnitRestDocumentation。
此外,您不需要 @Rule 注解。
以下示例展示了如何使用 ManualRestDocumentation:
private ManualRestDocumentation restDocumentation = new ManualRestDocumentation();
其次,您必须在每个测试之前调用 ManualRestDocumentation.beforeTest(Class, String)。
您可以将其作为配置 MockMvc、WebTestClient 或 REST Assured 的方法的一部分来完成。
以下示例展示了如何执行此操作:
private MockMvc mockMvc;
@Autowired
private WebApplicationContext context;
@BeforeMethod
public void setUp(Method method) {
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context)
.apply(documentationConfiguration(this.restDocumentation))
.build();
this.restDocumentation.beforeTest(getClass(), method.getName());
}
private WebTestClient webTestClient;
@Autowired
private ApplicationContext context;
@BeforeMethod
public void setUp(Method method) {
this.webTestClient = WebTestClient.bindToApplicationContext(this.context)
.configureClient()
.filter(documentationConfiguration(this.restDocumentation)) (1)
.build();
this.restDocumentation.beforeTest(getClass(), method.getName());
}
private RequestSpecification spec;
@BeforeMethod
public void setUp(Method method) {
this.spec = new RequestSpecBuilder().addFilter(documentationConfiguration(this.restDocumentation)).build();
this.restDocumentation.beforeTest(getClass(), method.getName());
}
最后,您必须在每个测试后调用 ManualRestDocumentation.afterTest。
以下示例展示了如何使用 TestNG 执行此操作:
@AfterMethod
public void tearDown() {
this.restDocumentation.afterTest();
}
调用 RESTful 服务
现在您已经配置好了测试框架,可以使用它来调用 RESTful 服务并记录请求和响应。 以下示例展示了如何实现这一点:
this.mockMvc.perform(get("/").accept(MediaType.APPLICATION_JSON)) (1)
.andExpect(status().isOk()) (2)
.andDo(document("index")); (3)
| 1 | 调用服务的根(/),并指示需要 application/json 响应。 |
| 2 | 断言服务产生了预期的响应。 |
| 3 | 记录对服务的调用,将代码片段写入名为 index 的目录(该目录位于配置的输出目录之下)。
这些代码片段由 RestDocumentationResultHandler 生成。
您可以通过调用 org.springframework.restdocs.mockmvc.MockMvcRestDocumentation 上的静态 document 方法来获取该类的实例。 |
this.webTestClient.get()
.uri("/")
.accept(MediaType.APPLICATION_JSON) (1)
.exchange()
.expectStatus()
.isOk() (2)
.expectBody()
.consumeWith(document("index")); (3)
| 1 | 调用服务的根(/),并指示需要 application/json 响应。 |
| 2 | 断言服务产生了预期的响应。 |
| 3 | 记录对服务的调用,将代码片段写入名为 index 的目录(该目录位于配置的输出目录之下)。
这些代码片段由 ExchangeResult 的 Consumer 写入。
您可以通过 org.springframework.restdocs.webtestclient.WebTestClientRestDocumentation 上的静态 document 方法获取此类消费者。 |
RestAssured.given(this.spec) (1)
.accept("application/json") (2)
.filter(document("index")) (3)
.when()
.get("/") (4)
.then()
.assertThat()
.statusCode(is(200)); (5)
| 1 | 应用已在 @Before 方法中初始化的规范。 |
| 2 | 指示需要 application/json 响应。 |
| 3 | 记录对服务的调用,将代码片段写入名为 index 的目录(该目录位于配置的输出目录之下)。
这些代码片段由 RestDocumentationFilter 生成。
您可以从 org.springframework.restdocs.restassured 包中 RestAssuredRestDocumentation 类的静态 document 方法获取该类的实例。 |
| 4 | 调用服务的根 (/)。 |
| 5 | 断言服务产生预期的响应。 |
默认情况下,会写入六个代码片段:
-
<output-directory>/index/curl-request.adoc -
<output-directory>/index/http-request.adoc -
<output-directory>/index/http-response.adoc -
<output-directory>/index/httpie-request.adoc -
<output-directory>/index/request-body.adoc -
<output-directory>/index/response-body.adoc
有关 Spring REST Docs 可生成的这些及其他代码片段的更多信息,请参阅 API 文档编写指南。
使用代码片段
在使用生成的代码片段之前,您必须创建一个 .adoc 源文件。
您可以将该文件命名为任何名称,只要它具有 .adoc 后缀即可。
生成的 HTML 文件具有相同的名称,但带有 .html 后缀。
源文件和生成的 HTML 文件的默认位置取决于您是使用 Maven 还是 Gradle:
| 构建工具 | 源文件 | 生成的文件 |
|---|---|---|
Maven |
|
|
Gradle |
|
|
然后,您可以使用 include 宏 将生成的代码片段包含在手动创建的 Asciidoc 文件(本节前面已描述)中。
您可以使用由 构建配置 中配置的 spring-restdocs-asciidoctor 自动设置的 snippets 属性来引用代码片段输出目录。
以下示例展示了如何操作:
include::{snippets}/index/curl-request.adoc[]