# 43.3.18 自动配置的Spring REST Docs测试

为了在测试里使用[Spring REST Docs](https://projects.spring.io/spring-restdocs/)，你可以使用`@AutoConfigureRestDocs`注解。它移除了Spring REST Docs里对JUnit规则的需要。

`@AutoConfigureRestDocs`可用于覆盖默认的输出目录（如果你使用Maven，目录是`target/generated-snippets`。如果你使用Gradle，则是`build/generated-snippets`）。它也可以用于配置出现在任何文档化的URI里的主机、方案、端口。

**使用Mock MVC的自动配置的Spring REST Docs测试**

`@AutoConfigureRestDocs`自定义`MockMvc` bean来使用Spring REST Docs。当你使用Mock MVC和Spring REST Docs时，你可以使用`@Autowired`将其注入，好在测试里使用。如下所示：

```java
import org.junit.Test;
import org.junit.runner.RunWith;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;

import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

@RunWith(SpringRunner.class)
@WebMvcTest(UserController.class)
@AutoConfigureRestDocs
public class UserDocumentationTests {

    @Autowired
    private MockMvc mvc;

    @Test
    public void listUsers() throws Exception {
        this.mvc.perform(get("/users").accept(MediaType.TEXT_PLAIN))
                .andExpect(status().isOk())
                .andDo(document("list-users"));
    }

}
```

`@AutoConfigureRestDocs`能够用于覆盖默认的输出目录（如果你使用的是Maven，默认的输出目录是`target/generated-snippets`。使用的是Gradle的话，就是`build/generated-snippets`）。`@AutoConfigureRestDocs`也能配置将出现在任何文档化的URLs中的部分，比如host，scheme和port等。如果需要控制更多Spring REST Docs的配置，你可以使用`RestDocsMockMvcConfigurationCustomizer` bean：

如果你需要控制更多的Spring REST Docs的配置，这些配置超出了`@AutoConfigureRestDocs`属性提供的范围。那么，你可以使用`RestDocsMockMvcConfigurationCustomizer` bean。如下所示：

```java
@TestConfiguration
static class CustomizationConfiguration
        implements RestDocsMockMvcConfigurationCustomizer {

    @Override
    public void customize(MockMvcRestDocumentationConfigurer configurer) {
        configurer.snippets().withTemplateFormat(TemplateFormats.markdown());
    }

}
```

如果想充分利用Spring REST Docs对参数化输出目录的支持，你可以创建一个`RestDocumentationResultHandler` bean，自动配置将使用它调用`alwaysDo`方法，进而促使每个`MockMvc`调用都会自动产生默认片段。下面的例子展示了一个定义好的`RestDocumentationResultHandler`：

```java
@TestConfiguration
static class ResultHandlerConfiguration {

    @Bean
    public RestDocumentationResultHandler restDocumentation() {
        return MockMvcRestDocumentation.document("{method-name}");
    }

}
```

**使用REST Assured的自动配置的Spring REST Docs测试**

`@AutoConfigureRestDocs`创建了一个`RequestSpecification` bean，预配置为使用Spring REST Docs。当你使用REST Assured和Spring REST Docs时，你可以使用`@Autowired`将其注入，好在测试里使用。如下所示：

```java
import io.restassured.specification.RequestSpecification;
import org.junit.Test;
import org.junit.runner.RunWith;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.test.context.junit4.SpringRunner;

import static io.restassured.RestAssured.given;
import static org.hamcrest.CoreMatchers.is;
import static org.springframework.restdocs.restassured3.RestAssuredRestDocumentation.document;

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
@AutoConfigureRestDocs
public class UserDocumentationTests {

    @LocalServerPort
    private int port;

    @Autowired
    private RequestSpecification documentationSpec;

    @Test
    public void listUsers() {
        given(this.documentationSpec).filter(document("list-users")).when()
                .port(this.port).get("/").then().assertThat().statusCode(is(200));
    }

}
```

如果你需要控制更多的Spring REST Docs的配置，这些配置超出了`@AutoConfigureRestDocs`属性提供的范围。那么，你可以使用`RestDocsRestAssuredConfigurationCustomizer` bean。如下所示：

```java
@TestConfiguration
public static class CustomizationConfiguration
        implements RestDocsRestAssuredConfigurationCustomizer {

    @Override
    public void customize(RestAssuredRestDocumentationConfigurer configurer) {
        configurer.snippets().withTemplateFormat(TemplateFormats.markdown());
    }

}
```
