如何为合约提供动态值?
与存根相关的一大挑战在于其可重用性。只有当它们能够被广泛使用时,才能发挥其作用。请求和响应元素中的硬编码值(如日期和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"
}
在前面的章节中,我们从合约生成了测试。因此,从生产者(producer)的角度来看,情况就大不相同了。我们解析提供的合约,并在测试中向你的端点发送真实的请求。因此,对于生产者处理请求的情况,我们不能有任何形式的匹配(matching)。我们需要具体的值,以便生产者的后端能够处理。因此,下面的 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 允许你提供一个动态值。这意味着通信双方的值可以不同。
你可以在合约DSL部分了解更多相关内容。
阅读 Groovy 文档中关于 JSON 的部分 以了解如何正确构建请求和响应体。