API 文件
使用 Spring REST Docs 來記錄你的服務。它是一個功能強大的框架,可確保服務邏輯始終與文件內聯。為此,你必須為你的服務編寫整合測試。
如果文件和服務行為不匹配,測試將失敗。
以下是為 maven 專案生成文件的示例示例。
在你的 pom 中新增這個依賴:
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-rest-webmvc</artifactId>
<version>2.6.6.RELEASE</version>
</dependency>
並在 build.plugins 標記下新增 asciidoc 外掛:
<plugin>
<groupId>org.asciidoctor</groupId>
<artifactId>asciidoctor-maven-plugin</artifactId>
<version>1.5.3</version>
<executions>
<execution>
<id>generate-docs</id>
<phase>prepare-package</phase>
<goals>
<goal>process-asciidoc</goal>
</goals>
<configuration>
<backend>html</backend>
<doctype>book</doctype>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.springframework.restdocs</groupId>
<artifactId>spring-restdocs-asciidoctor</artifactId>
<version>1.2.0.RELEASE</version>
</dependency>
</dependencies>
</plugin>
現在讓我們拿一個我們想要記錄的樣本控制器:
package com.hospital.user.service.controller;
import org.springframework.hateoas.Resource;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.hospital.user.service.entity.User;
import com.hospital.user.service.exception.UserNotFoundException;
import com.hospital.user.service.repository.UserCrudRepository;
import com.hospital.user.service.resource.assembler.UserResourceAssembler;
@Controller
@RequestMapping("/api/user")
public class SampleController {
final UserCrudRepository userRepository;
final UserResourceAssembler userResourceAssembler;
final BCryptPasswordEncoder passwordEncoder;
public SampleController(UserCrudRepository userCrudRepository, UserResourceAssembler userResourceAssembler, BCryptPasswordEncoder passwordEncoder){
this.userRepository = userCrudRepository;
this.userResourceAssembler = userResourceAssembler;
this.passwordEncoder = passwordEncoder;
}
@RequestMapping(method = RequestMethod.GET, value = "/{userId}", produces = { MediaType.APPLICATION_JSON_VALUE})
ResponseEntity<Resource<User>> getUser(@PathVariable String userId){
User user = (User) this.userRepository.findOne(userId);
if(user==null){
throw new UserNotFoundException("No record found for userid"+ userId);
}
Resource<User> resource = this.userResourceAssembler.toResource(user);
return new ResponseEntity<Resource<User>>(resource, HttpStatus.OK);
}
}
現在為服務編寫一個測試用例:
package com.hospital.user.service;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.restdocs.JUnitRestDocumentation;
import org.springframework.restdocs.mockmvc.RestDocumentationResultHandler;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import static org.springframework.restdocs.operation.preprocess.Preprocessors.prettyPrint;
import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessRequest;
import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessResponse;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
import static org.springframework.restdocs.headers.HeaderDocumentation.headerWithName;
import static org.springframework.restdocs.headers.HeaderDocumentation.responseHeaders;
import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath;
import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields;
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@EnableWebMvc
@ComponentScan( basePackages = { "com.hospital.user.service" } )
@SpringBootTest
public class SampleControllerTest {
private RestDocumentationResultHandler documentationHandler;
@Rule public final JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation("target/generated-snippets");
@Autowired private WebApplicationContext context;
private MockMvc mockMvc;
@Before
public void setUp(){
this.documentationHandler = document("{method-name}", //this will create files with the test method name
preprocessRequest(prettyPrint()), // to print the request
preprocessResponse(prettyPrint()));
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context)
.apply(documentationConfiguration(this.restDocumentation)
.uris()
//.withScheme("https") Specify this for https
.withHost("recruitforceuserservice") //Define the host name
.withPort(8443)
)
.alwaysDo(this.documentationHandler)
.build();
}
@Test
public void getUser() throws Exception {
// tag::links[]
this.mockMvc.perform(get("/api/user/"+"591310c3d5eb3a37183ab0d3").header("Authorization",
"Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJiaGFyZHdhai5uaXRpc2gxOSIsInJvbGVzIjpbIkFETUlOIl0sImlzcyI6Imh0dHA6Ly9ob3NwaXRhbC1jbG91ZC5jb20iLCJpYXQiOjE1MDExNTA3NDcsImV4cCI6MTUwMTE1MTY0N30.NPumYw9mslHdJjaaodsIzKX4y0Udbf2Co1kVOXBEaqNdEUIUSwgwQZn23TMWVsehudlwTu4KgCU2ZHXXccCDIQ"))
.andExpect(status().isOk())
.andDo(this.documentationHandler.document(
responseHeaders(
headerWithName("Content-Type").description("The Content-Type of the payload: `application/json`") // Asserts that the response should have this header.
),
responseFields(
fieldWithPath("username").description("Unique name for the record"), // Asserts that the response should have this field
fieldWithPath("password").description("password of the user"),
fieldWithPath("securityAnswer").description("Security answer which would be used to validate the user while the password is reset."),
fieldWithPath("securityQuestion").description("Security question to reset the password"),
fieldWithPath("email").description("Email of the user"),
fieldWithPath("roles").description("Assigned roles of the user"),
fieldWithPath("id").description("Unique identifier of an user"),
fieldWithPath("_links").ignored()
)
));
}
}
請關注此參考以獲取更多詳細資訊: http : //docs.spring.io/spring-restdocs/docs/current/reference/html5/