开始

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

要求

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

此外,spring-restdocs-restassured模块需要 REST Assured 5.2。spring-doc.cadn.net.cn

构建配置

使用 Spring REST Docs 的第一步是配置项目的构建。 Spring HATEOASSpring Data REST 示例包含一个build.gradlepom.xml,您可能希望将其用作参考。 以下清单描述了配置的关键部分:spring-doc.cadn.net.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 添加依赖项spring-restdocs-mockmvctest范围。 如果您想使用WebTestClient或 REST Assured 而不是 MockMvc,请添加对spring-restdocs-webtestclientspring-restdocs-restassured相反。
2 添加 Asciidoctor 插件。
3 prepare-package允许将文档包含在包中
4 spring-restdocs-asciidoctor作为 Asciidoctor 插件的依赖项。 这将自动配置snippets属性,以便在.adoc要指向的文件target/generated-snippets. 它还允许您使用operationblock 宏。
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 声明asciidoctorExt配置。
3 添加依赖项spring-restdocs-asciidoctorasciidoctorExt配置。 这将自动配置snippets属性,以便在.adoc要指向的文件build/generated-snippets. 它还允许您使用operationblock 宏。
4 添加依赖项spring-restdocs-mockmvctestImplementation配置。 如果您想使用WebTestClient或 REST Assured 而不是 MockMvc,请添加对spring-restdocs-webtestclientspring-restdocs-restassured相反。
5 配置snippetsDir定义生成代码片段的输出位置的属性。
6 让 Gradle 知道运行testtask 会将输出写入 snippetsDir。这是增量构建所必需的。
7 配置asciidoctor任务。
8 让 Gradle 知道运行该任务将从 snippetsDir 中读取输入。这是增量构建所必需的。
9 配置asciidoctorExt配置。
10 使任务依赖于test任务,以便在创建文档之前运行测试。

打包文档

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

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

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

下面的清单显示了如何在 Maven 和 Gradle 中执行此作:spring-doc.cadn.net.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 插件之后声明,因为它们被绑定到同一个阶段(prepare-package),并且资源插件必须在 Asciidoctor 插件之后运行,以确保在复制之前生成文档。 如果您没有使用 Spring Boot 及其插件管理,请使用适当的<version>.
3 将生成的文档复制到构建输出的static/docs目录中,它将从该目录中包含在 JAR 文件中。
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.cadn.net.cn

设置测试

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

设置 JUnit 5 测试

使用 JUnit 5 时,生成文档片段的第一步是将RestDocumentationExtension添加到您的测试类中。 以下示例显示了如何执行此作:spring-doc.cadn.net.cn

@ExtendWith(RestDocumentationExtension.class)
public class JUnit5ExampleTests {

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

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

RestDocumentationExtension会根据项目的构建工具自动配置输出目录:spring-doc.cadn.net.cn

构建工具 输出目录

Maven 系列spring-doc.cadn.net.cn

target/generated-snippetsspring-doc.cadn.net.cn

Gradlespring-doc.cadn.net.cn

build/generated-snippetsspring-doc.cadn.net.cn

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

public class JUnit5ExampleTests {

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

}

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

MockMvc
private MockMvc mockMvc;

@BeforeEach
void setUp(WebApplicationContext webApplicationContext, RestDocumentationContextProvider restDocumentation) {
	this.mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext)
		.apply(documentationConfiguration(restDocumentation)) (1)
		.build();
}
1 MockMvc实例是使用MockMvcRestDocumentationConfigurer. 您可以从静态documentationConfiguration()method 开启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 WebTestClient实例通过添加WebTestClientRestDocumentationConfigurer作为ExchangeFilterFunction. 您可以从静态documentationConfiguration()method 开启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 的配置是通过添加RestAssuredRestDocumentationConfigurer作为Filter. 您可以从静态documentationConfiguration()method 开启RestAssuredRestDocumentationorg.springframework.restdocs.restassured包。

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

设置 JUnit 4 测试

使用 JUnit 4 时,生成文档片段的第一步是声明public JUnitRestDocumentation字段,该字段被批注为 JUnit@Rule. 以下示例显示了如何执行此作:spring-doc.cadn.net.cn

@Rule
public JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation();

默认情况下,JUnitRestDocumentationrule 会根据项目的构建工具自动配置输出目录:spring-doc.cadn.net.cn

构建工具 输出目录

Maven 系列spring-doc.cadn.net.cn

target/generated-snippetsspring-doc.cadn.net.cn

Gradlespring-doc.cadn.net.cn

build/generated-snippetsspring-doc.cadn.net.cn

您可以通过在创建JUnitRestDocumentation实例。 以下示例显示了如何执行此作:spring-doc.cadn.net.cn

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

接下来,您必须提供@Before方法来配置 MockMvc 或 WebTestClient 或 REST Assured。 以下示例说明如何执行此作:spring-doc.cadn.net.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 MockMvc实例是使用MockMvcRestDocumentationConfigurer. 您可以从静态documentationConfiguration()method 开启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 WebTestClient实例通过添加WebTestclientRestDocumentationConfigurer作为ExchangeFilterFunction. 您可以从静态documentationConfiguration()method 开启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 的配置是通过添加RestAssuredRestDocumentationConfigurer作为Filter. 您可以从静态documentationConfiguration()method 开启RestAssuredRestDocumentationorg.springframework.restdocs.restassured包。

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

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

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

第一个区别是您应该使用ManualRestDocumentation代替JUnitRestDocumentation. 此外,您不需要@Rule注解。 以下示例演示如何使用ManualRestDocumentation:spring-doc.cadn.net.cn

private ManualRestDocumentation restDocumentation = new ManualRestDocumentation();

其次,您必须调用ManualRestDocumentation.beforeTest(Class, String)在每次测试之前。 您可以将此作作为配置 MockMvc、WebTestClient 或 REST Assure 的方法的一部分。 以下示例说明如何执行此作:spring-doc.cadn.net.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());
}

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

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

调用 RESTful 服务

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

MockMvc
this.mockMvc.perform(get("/").accept(MediaType.APPLICATION_JSON)) (1)
	.andExpect(status().isOk()) (2)
	.andDo(document("index")); (3)
1 调用服务的根 () 并指示/application/json需要回复。
2 断言服务生成了预期的响应。
3 记录对服务的调用,将代码段写入名为index(位于配置的输出目录下方)。 这些代码段由RestDocumentationResultHandler. 您可以从静态documentmethod 开启org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.
WebTest客户端
this.webTestClient.get()
	.uri("/")
	.accept(MediaType.APPLICATION_JSON) (1)
	.exchange()
	.expectStatus()
	.isOk() (2)
	.expectBody()
	.consumeWith(document("index")); (3)
1 调用服务的根 () 并指示/application/json需要回复。
2 断言服务生成了预期的响应。
3 记录对服务的调用,将代码段写入名为index(位于配置的输出目录下方)。 这些代码段由ConsumerExchangeResult. 您可以从 static 获取这样的 Consumerdocumentmethod 开启org.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 记录对服务的调用,将代码段写入名为index(位于配置的输出目录下方)。 这些代码段由RestDocumentationFilter. 您可以从静态documentmethod 开启RestAssuredRestDocumentationorg.springframework.restdocs.restassured包。
4 调用服务的 root ()。/
5 断言服务生成预期的响应。

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

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

使用 Snippets

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

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

Maven 系列spring-doc.cadn.net.cn

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

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

Gradlespring-doc.cadn.net.cn

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

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

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

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