SpringCloud 这个值是什么(consumer(),producer())?
与存根相关的最大挑战之一是它们的可重用性。只有将它们广泛使用,它们才能达到目的。通常使困难的是请求/响应元素的硬编码值。例如日期或ID。想象以下JSON请求
{ "time" : "2016-10-10 20:10:15", "id" : "9febab1c-6f36-4a0b-88d6-3b6a6d81cd4a", "body" : "foo" }
和JSON响应
{ "time" : "2016-10-10 21:10:15", "id" : "c4231e1f-3ca9-48d3-b7e7-567d55f0d051", "body" : "bar" }
想象一下通过更改系统中的时钟或提供数据提供者的存根实现来设置time
字段的适当值(让我们假定此内容是由数据库生成)所需的痛苦。与名为id
的字段相同。您将创建UUID生成器的存根实现吗?毫无意义...
因此,作为消费者,您希望发送与任何时间形式或任何UUID匹配的请求。这样,您的系统将像往常一样工作-会生成数据,而您无需存根任何东西。假设在上述JSON的情况下,最重要的部分是body
字段。您可以专注于此并为其他字段提供匹配。换句话说,您希望存根像这样工作:
{ "time" : "SOMETHING THAT MATCHES TIME", "id" : "SOMETHING THAT MATCHES UUID", "body" : "foo" }
就响应作为消费者而言,您需要可以操作的具体价值。所以这样的JSON是有效的
{ "time" : "2016-10-10 21:10:15", "id" : "c4231e1f-3ca9-48d3-b7e7-567d55f0d051", "body" : "bar" }
如您在前几节中所看到的,我们根据合同生成测试。因此,从生产者的角度来看,情况似乎大不相同。我们正在解析提供的合同,并且在测试中我们想向您的端点发送真实请求。因此,对于请求的生产者而言,我们无法进行任何形式的匹配。我们需要生产者后端可以使用的具体价值。这样的JSON是有效的:
{ "time" : "2016-10-10 20:10:15", "id" : "9febab1c-6f36-4a0b-88d6-3b6a6d81cd4a", "body" : "foo" }
另一方面,从合同有效性的角度来看,响应不一定包含time
或id
的具体值。假设您是在生产者端生成的-再次,您必须进行大量的存根操作以确保始终返回相同的值。因此,从生产者的角度来看,您可能想要以下响应:
{ "time" : "SOMETHING THAT MATCHES TIME", "id" : "SOMETHING THAT MATCHES UUID", "body" : "bar" }
那么,您如何才能一次为消费者提供匹配者,为生产者提供具体价值,反之亦然?在Spring Cloud Contract中,我们允许您提供动态值。这意味着通信的双方可能会有所不同。您可以传递值:
通过value
方法
value(consumer(...), producer(...)) value(stub(...), test(...)) value(client(...), server(...))
或使用$()
方法
$(consumer(...), producer(...)) $(stub(...), test(...)) $(client(...), server(...))
您可以在Contract DSL部分中了解有关此内容的更多信息。
调用value()
或$()
会告诉Spring Cloud Contract您将传递动态值。在consumer()
方法内部,传递应该在使用者方(在生成的存根中)使用的值。在producer()
方法内部,传递应该在生产方(在生成的测试中)使用的值。
如果一侧传递了正则表达式,而另一侧则没有传递,则另一侧将自动生成。
通常,您会将该方法与regex
帮助方法一起使用。例如consumer(regex('[0-9]{10}'))
。
概括起来,上述情况的合同看起来或多或少像这样(时间和UUID的正则表达式已简化,很可能是无效的,但在此示例中,我们希望保持非常简单):
org.springframework.cloud.contract.spec.Contract.make { request { method 'GET' url '/someUrl' body([ time : value(consumer(regex('[0-9]{4}-[0-9]{2}-[0-9]{2} [0-2][0-9]-[0-5][0-9]-[0-5][0-9]')), id: value(consumer(regex('[0-9a-zA-z]{8}-[0-9a-zA-z]{4}-[0-9a-zA-z]{4}-[0-9a-zA-z]{12}')) body: "foo" ]) } response { status OK() body([ time : value(producer(regex('[0-9]{4}-[0-9]{2}-[0-9]{2} [0-2][0-9]-[0-5][0-9]-[0-5][0-9]')), id: value([producer(regex('[0-9a-zA-z]{8}-[0-9a-zA-z]{4}-[0-9a-zA-z]{4}-[0-9a-zA-z]{12}')) body: "bar" ]) } }
请阅读与JSON相关的Groovy文档,以了解如何正确构造请求/响应主体。
更多建议: