Spring boot 使用SpringREST文档记录空值

Spring boot 使用SpringREST文档记录空值,spring-boot,mockmvc,spring-restdocs,Spring Boot,Mockmvc,Spring Restdocs,假设我们有以下API: @RestController 公共类个人控制器{ @GetMapping(“/api/person”) 公共列表findPeople(){ 返回数组.asList(newperson(“Doe”、“Foo”、“John”)、newperson(“Doe”、null、“Jane”); } } 其中模型类如下所示: @数据 @AllArgsConstructor @诺尔格构装师 公共阶层人士{ 私有字符串lastName; 私有字符串名称; 私有字符串名; } 正如您在

假设我们有以下API:

@RestController
公共类个人控制器{
@GetMapping(“/api/person”)
公共列表findPeople(){
返回数组.asList(newperson(“Doe”、“Foo”、“John”)、newperson(“Doe”、null、“Jane”);
}
}
其中模型类如下所示:

@数据
@AllArgsConstructor
@诺尔格构装师
公共阶层人士{
私有字符串lastName;
私有字符串名称;
私有字符串名;
}
正如您在控制器中看到的,列表中第二个对象的
middleName
属性是
null
。我现在尝试使用Spring REST文档来记录API的属性,因此我编写了以下测试:

@测试
public void findAllReturnsOple()引发异常{
mockMvc.perform(get(“/api/person”).accept(MediaType.APPLICATION_JSON))
.andExpect(jsonPath($[0].firstName),是(“John”))
.andExpect(jsonPath(“$[0].middleName”是(“Foo”))
.andExpect(jsonPath($[0].lastName)是(“Doe”))
.andExpect(jsonPath(“$[1].firstName”)是(“Jane”))
.andExpect(jsonPath(“$[1].middleName”,nullValue()))
.andExpect(jsonPath(“$[1].lastName”)是(“Doe”))
.andDo(文档(“人员获取”),响应字段(
fieldWithPath(“[].firstName”).description(“一个人的名字”),
fieldWithPath(“[].middleName”).description(“一个人的可选中间名”),
fieldWithPath(“[].lastName”).description(“某人的姓氏”);
}
通过使用
responseFields()
fieldWithPath()
属性,我试图对每个字段进行描述。但是,这种方法对于中间名失败,引发以下异常:

org.springframework.restdocs.snippet.SnippetException:在有效负载中找不到具有以下路径的字段:[[].middleName]
位于org.springframework.restdocs.payload.AbstractFieldsSnippet.validateFieldDocumentation(AbstractFieldsSnippet.java:257)
位于org.springframework.restdocs.payload.AbstractFieldsNippet.createModel(AbstractFieldsNippet.java:167)
位于org.springframework.restdocs.snippet.TemplatedSnippet.document(TemplatedSnippet.java:83)
位于org.springframework.restdocs.generate.RestDocumentationGenerator.handle(RestDocumentationGenerator.java:206)
位于org.springframework.restdocs.mockmvc.RestDocumentationResultHandler.handle(RestDocumentationResultHandler.java:55)
位于org.springframework.test.web.servlet.MockMvc$1.andDo(MockMvc.java:183)
位于be.g00glen00b.apps.demoempty.DemoEmptyApplicationTests.findAllReturnsPeople(DemoEmptyApplicationTests.java:37)
在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)处
位于sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)中
位于java.lang.reflect.Method.invoke(Method.java:498)
位于org.junit.runners.model.FrameworkMethod$1.runReflectVeCall(FrameworkMethod.java:50)
位于org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
位于org.junit.runners.model.FrameworkMethod.invokeeexplosive(FrameworkMethod.java:47)
位于org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
位于org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:73)
位于org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:83)
位于org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
位于org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
位于org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
位于org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
位于org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)
位于org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
位于org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
位于org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
位于org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
访问org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
位于org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
位于org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
位于org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
位于org.junit.runners.ParentRunner.run(ParentRunner.java:363)
位于org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
位于org.junit.runner.JUnitCore.run(JUnitCore.java:137)
位于com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
位于com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
位于com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
位于com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
但是,当我更改代码并将第二个
对象的中间名更改为
“Bar”
时,错误消失,代码段正确生成

此外,当我删除
字段WithPath(“[].middleName”)
代码并运行测试时,我得到以下异常:

org.springframework.restdocs.snippet.SnippetException:
.andDo(document("person-get", responseFields(
        fieldWithPath("[].firstName").description("The given name of a person"),
        fieldWithPath("[].middleName").description("The optionally given middle name of a person").optional(),
        fieldWithPath("[].lastName").description("The last- or family name of a person"))));