开始

本节介绍如何开始使用 Spring REST Docs。spring-doc.cn

要求

Spring REST Docs 具有以下最低要求:spring-doc.cn

此外,该模块需要 REST Assured 5.2。spring-restdocs-restassuredspring-doc.cn

构建配置

使用 Spring REST Docs 的第一步是配置项目的构建。 Spring HATEOASSpring Data REST 示例分别包含 a 和 ,您可能希望将其用作参考。 以下清单描述了配置的关键部分:build.gradlepom.xmlspring-doc.cn

Maven 系列
<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 在范围中添加依赖项。 如果要使用 or REST Assured 而不是 MockMvc,请分别添加对 或 的依赖项。spring-restdocs-mockmvctestWebTestClientspring-restdocs-webtestclientspring-restdocs-restassured
2 添加 Asciidoctor 插件。
3 使用 允许将文档包含在包中prepare-package
4 添加为 Asciidoctor 插件的依赖项。 这将自动配置用于文件的属性以指向 . 它还将允许您使用 block 宏。spring-restdocs-asciidoctorsnippets.adoctarget/generated-snippetsoperation
Gradle
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 在配置中添加依赖项。 这将自动配置用于文件的属性以指向 . 它还将允许您使用 block 宏。spring-restdocs-asciidoctorasciidoctorExtsnippets.adocbuild/generated-snippetsoperation
4 在配置中添加依赖项。 如果要使用 or REST Assured 而不是 MockMvc,请分别添加对 或 的依赖项。spring-restdocs-mockmvctestImplementationWebTestClientspring-restdocs-webtestclientspring-restdocs-restassured
5 配置一个属性,用于定义生成的代码片段的输出位置。snippetsDir
6 让 Gradle 知道运行该任务会将输出写入 snippetsDir。这是增量构建所必需的。test
7 配置任务。asciidoctor
8 让 Gradle 知道运行该任务将从 snippetsDir 中读取输入。这是增量构建所必需的。
9 配置对扩展的配置的使用。asciidoctorExt
10 使任务依赖于任务,以便在创建文档之前运行测试。test

打包文档

您可能希望将生成的文档打包到项目的 jar 文件中 — 例如,将其作为 Spring Boot 的静态内容提供。 为此,请配置项目的生成,以便:spring-doc.cn

  1. 文档是在构建 jar 之前生成的spring-doc.cn

  2. 生成的文档包含在 jar 中spring-doc.cn

下面的清单显示了如何在 Maven 和 Gradle 中执行此操作:spring-doc.cn

Maven 系列
<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 插件之后声明,因为它们绑定到相同的阶段 () 并且资源插件必须在 Asciidoctor 插件之后运行,以确保在复制之前生成文档。 如果您不使用 Spring Boot 及其插件管理,请使用适当的 .prepare-package<version>
3 将生成的文档复制到构建输出的目录中,从该目录将包含在 jar 文件中。static/docs
Gradle
bootJar {
	dependsOn asciidoctor (1)
	from ("${asciidoctor.outputDir}/html5") { (2)
		into 'static/docs'
	}
}
1 确保在构建 jar 之前已生成文档。
2 将生成的文档复制到 jar 的目录中。static/docs

生成文档片段

Spring REST Docs 使用 Spring MVC 的测试框架、Spring WebFlux 的WebTestClientREST Assured 向您正在记录的服务发出请求。 然后,它会为请求和生成的响应生成文档片段。spring-doc.cn

设置测试

您设置测试的具体方式取决于您使用的测试框架。 Spring REST Docs 为 JUnit 5 和 JUnit 4 提供了一流的支持。 建议使用 JUnit 5。 还支持其他框架,例如 TestNG,但需要稍微多一些的设置。spring-doc.cn

设置 JUnit 5 测试

使用 JUnit 5 时,生成文档片段的第一步是将 应用于测试类。 以下示例显示了如何执行此操作:RestDocumentationExtensionspring-doc.cn

@ExtendWith(RestDocumentationExtension.class)
public class JUnit5ExampleTests {

在测试典型的 Spring 应用程序时,您还应该应用:SpringExtensionspring-doc.cn

@ExtendWith({RestDocumentationExtension.class, SpringExtension.class})
public class JUnit5ExampleTests {

它会根据项目的构建工具自动配置输出目录:RestDocumentationExtensionspring-doc.cn

构建工具 输出目录

Maven 系列spring-doc.cn

target/generated-snippetsspring-doc.cn

Gradlespring-doc.cn

build/generated-snippetsspring-doc.cn

如果您使用的是 JUnit 5.1,则可以通过将扩展注册为测试类中的字段并在创建扩展时提供输出目录来覆盖默认值。 以下示例显示了如何执行此操作:spring-doc.cn

public class JUnit5ExampleTests {

	@RegisterExtension
	final RestDocumentationExtension restDocumentation = new RestDocumentationExtension ("custom");

}

接下来,您必须提供一种方法来配置 MockMvc 或 WebTestClient 或 REST Assured。 以下清单显示了如何执行此操作:@BeforeEachspring-doc.cn

MockMvc
private MockMvc mockMvc;

@BeforeEach
void setUp(WebApplicationContext webApplicationContext, RestDocumentationContextProvider restDocumentation) {
	this.mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext)
		.apply(documentationConfiguration(restDocumentation)) (1)
		.build();
}
1 实例是使用 . 您可以从 上的 static 方法获取此类的实例。MockMvcMockMvcRestDocumentationConfigurerdocumentationConfiguration()org.springframework.restdocs.mockmvc.MockMvcRestDocumentation
WebTest客户端
private WebTestClient webTestClient;

@BeforeEach
void setUp(ApplicationContext applicationContext, RestDocumentationContextProvider restDocumentation) {
	this.webTestClient = WebTestClient.bindToApplicationContext(applicationContext)
		.configureClient()
		.filter(documentationConfiguration(restDocumentation)) (1)
		.build();
}
1 通过将 a 添加为 . 您可以从 上的 static 方法获取此类的实例。WebTestClientWebTestClientRestDocumentationConfigurerExchangeFilterFunctiondocumentationConfiguration()org.springframework.restdocs.webtestclient.WebTestClientRestDocumentation
放心
private RequestSpecification spec;

@BeforeEach
void setUp(RestDocumentationContextProvider restDocumentation) {
	this.spec = new RequestSpecBuilder().addFilter(documentationConfiguration(restDocumentation)) (1)
		.build();
}
1 REST Assured 的配置方法是将 添加为 . 您可以从包中的 static 方法 on 获取此类的实例。RestAssuredRestDocumentationConfigurerFilterdocumentationConfiguration()RestAssuredRestDocumentationorg.springframework.restdocs.restassured

配置器应用合理的默认值,并提供用于自定义配置的 API。 有关更多信息,请参阅配置部分spring-doc.cn

设置 JUnit 4 测试

使用 JUnit 4 时,生成文档片段的第一步是声明一个注释为 JUnit 的字段。 以下示例显示了如何执行此操作:publicJUnitRestDocumentation@Rulespring-doc.cn

@Rule
public JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation();

默认情况下,该规则会根据项目的构建工具自动配置输出目录:JUnitRestDocumentationspring-doc.cn

构建工具 输出目录

Maven 系列spring-doc.cn

target/generated-snippetsspring-doc.cn

Gradlespring-doc.cn

build/generated-snippetsspring-doc.cn

您可以通过在创建实例时提供输出目录来覆盖默认值。 以下示例显示了如何执行此操作:JUnitRestDocumentationspring-doc.cn

@Rule
public JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation("custom");

接下来,您必须提供一种方法来配置 MockMvc 或 WebTestClient 或 REST Assured。 以下示例说明如何执行此操作:@Beforespring-doc.cn

MockMvc
private MockMvc mockMvc;

@Autowired
private WebApplicationContext context;

@Before
public void setUp() {
	this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context)
		.apply(documentationConfiguration(this.restDocumentation)) (1)
		.build();
}
1 实例是使用 . 您可以从 上的 static 方法获取此类的实例。MockMvcMockMvcRestDocumentationConfigurerdocumentationConfiguration()org.springframework.restdocs.mockmvc.MockMvcRestDocumentation
WebTest客户端
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 通过将 a 添加为 . 您可以从 上的 static 方法获取此类的实例。WebTestClientWebTestclientRestDocumentationConfigurerExchangeFilterFunctiondocumentationConfiguration()org.springframework.restdocs.webtestclient.WebTestClientRestDocumentation
放心
private RequestSpecification spec;

@Before
public void setUp() {
	this.spec = new RequestSpecBuilder().addFilter(documentationConfiguration(this.restDocumentation)) (1)
		.build();
}
1 REST Assured 的配置方法是将 添加为 . 您可以从包中的 static 方法 on 获取此类的实例。RestAssuredRestDocumentationConfigurerFilterdocumentationConfiguration()RestAssuredRestDocumentationorg.springframework.restdocs.restassured

配置器应用合理的默认值,并提供用于自定义配置的 API。 有关更多信息,请参阅配置部分spring-doc.cn

在没有 JUnit 的情况下设置测试

不使用 JUnit 时的配置与使用 JUnit 时的配置基本相似。 本节介绍主要区别。 TestNG 示例还说明了该方法。spring-doc.cn

第一个区别是您应该使用 . 此外,您不需要注释。 以下示例演示如何使用:ManualRestDocumentationJUnitRestDocumentation@RuleManualRestDocumentationspring-doc.cn

private ManualRestDocumentation restDocumentation = new ManualRestDocumentation();

其次,您必须在每次测试前致电。 您可以将此操作作为配置 MockMvc、WebTestClient 或 REST Assure 的方法的一部分。 以下示例说明如何执行此操作:ManualRestDocumentation.beforeTest(Class, String)spring-doc.cn

MockMvc
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());
}
WebTest客户端
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());
}

最后,您必须在每次测试后调用 以下示例显示了如何使用 TestNG 执行此操作:ManualRestDocumentation.afterTestspring-doc.cn

@AfterMethod
public void tearDown() {
	this.restDocumentation.afterTest();
}

调用 RESTful 服务

现在,您已经配置了测试框架,您可以使用它来调用 RESTful 服务并记录请求和响应。 以下示例说明如何执行此操作:spring-doc.cn

MockMvc
this.mockMvc.perform(get("/").accept(MediaType.APPLICATION_JSON)) (1)
	.andExpect(status().isOk()) (2)
	.andDo(document("index")); (3)
1 调用服务的 root () 并指示需要响应。/application/json
2 断言服务生成了预期的响应。
3 记录对服务的调用,将代码段写入名为 (位于配置的输出目录下) 的目录中。 代码段由 . 您可以从 上的 static 方法获取此类的实例。indexRestDocumentationResultHandlerdocumentorg.springframework.restdocs.mockmvc.MockMvcRestDocumentation
WebTest客户端
this.webTestClient.get()
	.uri("/")
	.accept(MediaType.APPLICATION_JSON) (1)
	.exchange()
	.expectStatus()
	.isOk() (2)
	.expectBody()
	.consumeWith(document("index")); (3)
1 调用服务的 root () 并指示需要响应。/application/json
2 断言服务生成了预期的响应。
3 记录对服务的调用,将代码段写入名为 (位于配置的输出目录下) 的目录中。 代码段由 . 您可以从 上的 static 方法获取这样的使用者。indexConsumerExchangeResultdocumentorg.springframework.restdocs.webtestclient.WebTestClientRestDocumentation
放心
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 记录对服务的调用,将代码段写入名为 (位于配置的输出目录下) 的目录中。 代码段由 . 您可以从包中的 static 方法 on 获取此类的实例。indexRestDocumentationFilterdocumentRestAssuredRestDocumentationorg.springframework.restdocs.restassured
4 调用服务的 root ()。/
5 断言服务生成预期的响应。

默认情况下,将写入 6 个代码段:spring-doc.cn

有关这些代码段以及 Spring REST Docs 可以生成的其他代码段的更多信息,请参见编写 API 文档。spring-doc.cn

使用 Snippets

在使用生成的代码段之前,您必须创建一个源文件。 您可以随意命名文件,只要它有后缀即可。 生成的 HTML 文件具有相同的名称,但带有后缀。 源文件和生成的 HTML 文件的默认位置取决于您使用的是 Maven 还是 Gradle:.adoc.adoc.htmlspring-doc.cn

构建工具 源文件 生成的文件

Maven 系列spring-doc.cn

src/main/asciidoc/*.adocspring-doc.cn

target/generated-docs/*.htmlspring-doc.cn

Gradlespring-doc.cn

src/docs/asciidoc/*.adocspring-doc.cn

build/asciidoc/html5/*.htmlspring-doc.cn

然后,您可以使用 include 宏将生成的代码片段包含在手动创建的 Asciidoc 文件(本节前面所述)中。 您可以使用在 build 配置中 configured 自动设置的属性来引用 snippets 输出目录。 以下示例显示了如何执行此操作:snippetsspring-restdocs-asciidoctorspring-doc.cn

include::{snippets}/index/curl-request.adoc[]