zoukankan      html  css  js  c++  java
  • springboot~mockMvc和asciidoctor生成基于TDD的API文档

    API文档是前端与后端快速开发,减少沟通成本的必要条件,有一份完善的文档是很必要的,由通过测试来生成文档的好处就是:测试数据有了,测试返回结果有了,而且可以对这些字段进行说明,很清晰,在springboot框架里,去使用mockMvc文档生成时,需要有以下几个步骤,大叔总结了一下,分享给大家。

    一 mockMvc包引用

    testCompile('org.springframework.restdocs:spring-restdocs-mockmvc')
    asciidoctor 'org.springframework.restdocs:spring-restdocs-asciidoctor'

    二 snippetsDir插件引用

    在buildscript块里添加如下代码

    maven {
    url "https://plugins.gradle.org/m2/"
    }
    mavenCentral()
    dependencies {
    classpath "org.asciidoctor:asciidoctor-gradle-jvm:2.0.0-rc.1"

    }

     添加插件

    apply plugin: "org.asciidoctor.convert"

    三 配置三大路径的地址,三大路径指,asciidoctor文档路径,生成的API文档目录和snippets目录

    jar {
        dependsOn asciidoctor
        from ("${asciidoctor.outputDir}/html5") {
            into 'static/docs'
        }
    }
    
    ext {
        snippetsDir = file('build/generated-snippets')
    }
    
    
    integTest {
        outputs.dir snippetsDir
    }
    
    asciidoctor {
    inputs.dir snippetsDir outputDir "build/asciidoc" dependsOn integTest sourceDir 'src/docs/asciidoc' }

    四 添加API接口

    @RestController
    public class DocController {
      public static final String DOC = "/doc/{name}";
      public static final String DOC_LIST = "/doc/list";
    
      @GetMapping(DOC)
      public Map<String, String> index(@PathVariable String name) {
        Map<String, String> maps = new HashMap<>();
        maps.put("name", "Hello");
        maps.put("sex", "1");
        maps.put("buyer", name);
        return maps;
      }
    }

    五 添加测试用例

    package test.lind.javaLindDay;
    
    import static org.hamcrest.Matchers.containsString;
    import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
    import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
    import static org.springframework.restdocs.operation.preprocess.Preprocessors.prettyPrint;
    import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath;
    import static org.springframework.restdocs.payload.PayloadDocumentation.relaxedRequestFields;
    import static org.springframework.restdocs.payload.PayloadDocumentation.relaxedResponseFields;
    import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName;
    import static org.springframework.restdocs.request.RequestDocumentation.pathParameters;
    import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
    import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
    import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
    
    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.restdocs.JUnitRestDocumentation;
    import org.springframework.restdocs.mockmvc.MockMvcRestDocumentation;
    import org.springframework.restdocs.payload.RequestFieldsSnippet;
    import org.springframework.restdocs.payload.ResponseFieldsSnippet;
    import org.springframework.restdocs.request.PathParametersSnippet;
    import org.springframework.test.context.ActiveProfiles;
    import org.springframework.test.context.junit4.SpringRunner;
    import org.springframework.test.web.servlet.MockMvc;
    import org.springframework.test.web.servlet.setup.MockMvcBuilders;
    import org.springframework.web.context.WebApplicationContext;
    import test.lind.javaLindDay.controller.DocController;
    
    @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
    @ActiveProfiles("integTest")//指定profile环境
    @RunWith(SpringRunner.class)
    public class MockMvcTest {
      static final ResponseFieldsSnippet orderResponseFieldsParameters = relaxedResponseFields(
          fieldWithPath("name").description("账号"),
          fieldWithPath("buyer").description("购买者"),
          fieldWithPath("sex").description("性别")
      );
      static final RequestFieldsSnippet orderRequestFieldsParameters = relaxedRequestFields(
          fieldWithPath("code").description("凭证号"),
          fieldWithPath("word").description("凭证字"),
          fieldWithPath("batch").description("批次")
      );
      static final PathParametersSnippet orderRequestPathParameters = pathParameters(
          parameterWithName("name").description("购买者")
      );
    
      @Rule
      public JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation();
    
      protected MockMvc mockMvc;
    
      @Autowired
      private WebApplicationContext context;
    
      @Before
      public void setUp() {
        this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context)
            .apply(MockMvcRestDocumentation.documentationConfiguration(restDocumentation)
                .uris().withScheme("http").withHost("localhost").withPort(8080)
                .and()
                .operationPreprocessors().withResponseDefaults(prettyPrint()))
            .build();
      }
    
    
      @Test
      public void get_orders() throws Exception {
        this.mockMvc.perform(
            get(DocController.DOC, "zzl"))
            .andDo(print())
            .andExpect(status().isOk())
            .andExpect(content().string(containsString("Hello")))
            .andDo(document("doc-index", orderRequestPathParameters, orderResponseFieldsParameters));
      }
    
      @Test
      public void get_list() throws Exception {
        this.mockMvc.perform(
            get(DocController.DOC_LIST))
            .andDo(print())
            .andExpect(status().isOk())
            .andDo(document("doc-list", orderResponseFieldsParameters));
      }
    }

    这里有个需要注意的地址,get静态方法的包应该是import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;否则会有找不到路由的

    错误,这点困扰了我很久。

    六 编译,打包,它会同时去下载API DOC所需要的文件

    gradle build

    最后,进入build/asciidoc/html5目录,浏览我们的API说明文件即可。

      

    感谢各位的阅读!

     

  • 相关阅读:
    WPF Image Binding Uri Source 失败解决办法
    redis哈希表数据类型键的设置
    redis字符串类型键的二进制操作
    redis字符串类型的基本命令
    redis字符串数据类型基本概念和应用场景
    redis键的迁移操作
    redis键的排序操作
    Redis键的序列化和反序列化
    Redis过期命令
    Redis键的基本操作
  • 原文地址:https://www.cnblogs.com/lori/p/9184579.html
Copyright © 2011-2022 走看看