由于HAL" _links"导致的restdocs SnippetException。来自spring-data-rest

时间:2016-12-12 18:51:37

标签: java spring spring-data-rest spring-restdocs

我的应用正在使用spring-data-restspring-restdocs。 我的设置非常标准;几乎完全从文档中复制,但我已经包含了下面的示例,以防我遗漏了某些内容。 当我的mvc测试运行时,它失败了:

org.springframework.restdocs.snippet.SnippetException: The following parts of the payload were not documented:
{
  "_links" : {
    "self" : {
      "href" : "https://my-api/item/10"
    },
    "item" : {
      "href" : "https://my-api/item/10"
    }
  }
}

这是我的测试代码:

@Rule
public JUnitRestDocumentation restDocs = new JUnitRestDocumentation("target/generated-snippets");
// ...
mockMvc = webAppContextSetup(wac) //WebApplicationContext
        .apply(documentationConfiguration(restDocs)
                       .uris()
                       .withHost("my-api")
                       .withPort(443)
                       .withScheme("https"))
        .build();
// ....
mockMvc.perform(get("/items/{id}", "10"))
               .andDo(documentation)

这是堆栈:

at org.springframework.restdocs.payload.AbstractFieldsSnippet.validateFieldDocumentation(AbstractFieldsSnippet.java:176)
at org.springframework.restdocs.payload.AbstractFieldsSnippet.createModel(AbstractFieldsSnippet.java:100)
at org.springframework.restdocs.snippet.TemplatedSnippet.document(TemplatedSnippet.java:64)
at org.springframework.restdocs.generate.RestDocumentationGenerator.handle(RestDocumentationGenerator.java:196)
at org.springframework.restdocs.mockmvc.RestDocumentationResultHandler.handle(RestDocumentationResultHandler.java:55)
at org.springframework.test.web.servlet.MockMvc$1.andDo(MockMvc.java:177)
at com.example.my.api.domain.MyRepositoryRestTest.findOne(MyRepositoryRestTest.java:36)

如何让spring-restdocsspring-data-rest玩得开心?

<小时/> 修改(S):

我的documentation实例定义如下:

ResultHandler documentation = document("items/findOne",
                                       preprocessRequest(prettyPrint(), maskLinks()),
                                       preprocessResponse(prettyPrint()),
                                       responseFields(
                                            fieldWithPath("name").description("Item name.")
                                            // Bunch more
                                       ));

正如@meistermeier指出的那样(并且the restdocs docs for ignoring links之后,我可以添加

links(linkWithRel("self").ignored(),
      linkWithRel("_self").ignored().optional()) // docs suggest this. /shrug

但这仍然让我:

SnippetException: Links with the following relations were not documented: [item]

似乎_links总是将自我引用回到同一个实体,对吧? 如何在不忽略每个测试的特定于实体的链接的情况下干净地处理此问题,例如:

links(linkWithRel("item").ignored())

即使我执行添加上述行(以便所有字段self _self curiesitem都是{{1} }和/或ignored()),测试结果返回到此问题顶部的原始错误。

2 个答案:

答案 0 :(得分:8)

  

似乎_links总是将自我引用带回同一个实体,对吧?

是的,没错。

我可能有你的解决方案忽略a small github sample中的某些链接。特别是部分:

mockMvc.perform(RestDocumentationRequestBuilders.get(beerLocation)).andExpect(status().isOk())
       .andDo(document("beer-get", links(
                linkWithRel("self").ignored(),
                linkWithRel("beerapi:beer").description("The <<beers, Beer resource>> itself"),
                linkWithRel("curies").ignored()
               ),
               responseFields(
                  fieldWithPath("name").description("The name of the tasty fresh liquid"),
                  fieldWithPath("_links").description("<<beer-links,Links>> to other resources")
               )
            ));

我完全忽略所有“生成的”字段,只为域创建文档条目。您的item链接将是我的beerapi:beer

我真的不知道这里的最佳做法是什么,但我会尽可能地记录,因为你可以尽可能使用asciidoctor链接(如<<beer-links,Links>>)来引用其他部分和更多文档。

答案 1 :(得分:0)

规范方法似乎正在使用restdocs文档中的内容。方法与https://stackoverflow.com/users/2650436/meistermeier解决方案中的方法一致。

可以在https://docs.spring.io/spring-restdocs/docs/current/reference/html5/#documenting-your-api-hypermedia-link-formats

上找到文档

示例代码:

.consumeWith(document("items",
       links(
               halLinks(), // <- this shorten things a bit
               linkWithRel("self").ignored(),
               linkWithRel("profile").ignored()
       ),