此版本仍在开发中,目前尚不被视为稳定版本。如需最新稳定版本,请使用 spring-cloud-contract 5.0.2spring-doc.cadn.net.cn

我如何向契约提供动态值?

关于桩(stubs)最大的挑战之一是它们的可重用性。只有当它们能够被广泛使用时,才能实现其目的。请求和响应元素中的硬编码值(如日期和ID)通常会使其变得困难。请考虑以下JSON请求:spring-doc.cadn.net.cn

{
    "time" : "2016-10-10 20:10:15",
    "id" : "9febab1c-6f36-4a0b-88d6-3b6a6d81cd4a",
    "body" : "foo"
}

现在考虑以下 JSON 响应:spring-doc.cadn.net.cn

{
    "time" : "2016-10-10 21:10:15",
    "id" : "c4231e1f-3ca9-48d3-b7e7-567d55f0d051",
    "body" : "bar"
}

想象一下,为 time 字段设置正确值所需的痛苦(假设此内容由数据库生成),这可能需要通过修改系统时钟或提供数据提供者的模拟实现来完成。同样的问题也适用于 id 字段。虽然你可以创建一个 UUID 生成器的模拟实现,但这样做意义不大。spring-doc.cadn.net.cn

因此,作为消费者,您希望发送一个与任何时间格式或任何 UUID 匹配的请求。这样,您的系统可以像往常一样工作,生成数据而无需进行任何模拟(stub)操作。假设在上述 JSON 中,最关键的部分是 body 字段。您可以专注于该字段,并为其他字段提供匹配规则。换句话说,您希望模拟服务按如下方式工作:spring-doc.cadn.net.cn

{
    "time" : "SOMETHING THAT MATCHES TIME",
    "id" : "SOMETHING THAT MATCHES UUID",
    "body" : "foo"
}

就响应而言,作为消费者,您需要一个具体的值,以便对其进行操作。因此,以下 JSON 是有效的:spring-doc.cadn.net.cn

{
    "time" : "2016-10-10 21:10:15",
    "id" : "c4231e1f-3ca9-48d3-b7e7-567d55f0d051",
    "body" : "bar"
}

在前面几节中,我们从契约生成了测试。因此,从生产者一方来看,情况就大不相同了。我们解析提供的契约,并且在测试中,我们希望向您的端点发送真实的请求。因此,对于生产者发起的请求情形,我们无法进行任何形式的匹配。我们需要具体的值,以便生产者的后端能够正常工作。因此,以下 JSON 将是有效的:spring-doc.cadn.net.cn

{
    "time" : "2016-10-10 20:10:15",
    "id" : "9febab1c-6f36-4a0b-88d6-3b6a6d81cd4a",
    "body" : "foo"
}

另一方面,从合同有效性角度来看,响应不一定必须包含 timeid 的具体值。假设你是在生产者端生成这些值。同样,你必须进行大量模拟(stubbing)操作,以确保始终返回相同的值。因此,从生产者端出发,你可能希望如下响应:spring-doc.cadn.net.cn

{
    "time" : "SOMETHING THAT MATCHES TIME",
    "id" : "SOMETHING THAT MATCHES UUID",
    "body" : "bar"
}

那么,您如何为消费者提供一个匹配器,同时为生产者提供一个具体值(反之亦然,在其他时间)?<br/>Spring Cloud Contract 允许您提供动态值。这意味着它在通信双方都可以不同。spring-doc.cadn.net.cn

您可以在此处的 契约 DSL 部分阅读更多相关内容。spring-doc.cadn.net.cn

阅读 与 JSON 相关的 Groovy 文档,以了解如何正确地构建请求和响应体。