如何为Spring REST Docs编写自定义类型验证器?

时间:2018-05-02 08:50:51

标签: spring spring-restdocs

在Spring REST Docs中,我可以记录JSON响应的字段。另外,我可以指定我可以传递JsonFieldType的类型,例如JsonFieldType.STRIGN。这实际上将被验证,这意味着测试将在例如而是返回一个数字。

(...)
    .andDo( document( "one-valid-connection",
          pathParameters( parameterWithName( "ip" ).description( "The requested IPv4 address." ) ),
          responseFields( 
                fieldWithPath( "username" ).type( JsonFieldType.STRING ).description( "The name of the user that initiated the connection." ),
                fieldWithPath( "ipAddress" ).type( JsonFieldType.STRING ).description( "The IPv4 address of the user." ),
                fieldWithPath( "startTime" ).type( JsonFieldType.STRING ).description( "The time (ISO 8601 format) when the connection has been initiated." ),
                fieldWithPath( "stopTime" ).type( JsonFieldType.STRING ).description( "The time (ISO 8601 format) when the connection has been terminated or `null` if connection is still active." )
           )
    ) );

我的问题是,是否可以编写自定义类型来支持,例如IP地址,ISO时间戳,枚举甚至有效数值范围,以支持自定义验证(例如正则表达式或更复杂的逻辑)?

作为伪代码,类似

          responseFields( 
                fieldWithPath( "username" ).type( JsonFieldType.STRING )
                fieldWithPath( "ipAddress" ).type( CustomTypes.IPV4_ADDRESS ),
                fieldWithPath( "startTime" ).type( CustomTypes.ISO8601_TIMESTAMP ),
                fieldWithPath( "stopTime" ).type( CustomTypes.ISO8601_TIMESTAMP ),
                fieldWithPath( "type" ).type( CustomTypes.CONNECTION_ENUM ),
                fieldWithPath( "duration" ).type( CustomTypes.createIntRange(0,999999) )
           )

1 个答案:

答案 0 :(得分:2)

恕我直言,没有任何理智,直接的解决方案(即仅利用开放Spring进行扩展的点)。

Spring Restdocs的主要目的是文档,而不是 validate API。当我浏览源代码时,仅针对预定义类型对有效负载的实际实例进行了测试。值不作进一步分析。尽管您可以将任何Object用作字段描述符类型,即您不仅限于JsonFieldType类的对象,但实际上整个对象仅转换为toString才能写入某些asciidoc文档中。 ,仅此而已。

顺便说一句,我elaborated也曾想过将Restdocs用作结构验证工具。就我而言,我最终找到了可接受的解决方案。 Spring Restdocs源代码非常封闭,因此,根据我对内部结构的探索经验,我建议您不要尝试使用任何有问题的解决方案,例如覆盖org.springframework.restdocs.payload.JsonContentHandler#determineFieldTypeorg.springframework.restdocs.payload.JsonFieldTypeResolver#resolveFieldType方法(这需要通过以下方式破坏可见性保护:还是类工具)。

另一个想法可能是使用bean validation annotations