Consumer-Driven Contracts: Stubs Per Consumer

在某些情况下,同一个端点的两个消费者希望得到两个不同的响应。

此方法还使你可以立即知道哪个使用者使用了api的哪一部分。你可以删除api产生的部分响应,并查看你的自动生成测试中的哪一个失败。如果没有任何失败,则可以安全删除该部分响应,因为没有人使用它。

请考虑以下针对名为 producer 的生产者定义的契约示例,它有两个消费者(foo-consumerbar-consumer):

Consumer foo-service
request {
   url '/foo'
   method GET()
}
response {
    status OK()
    body(
       foo: "foo"
    }
}
Consumer bar-service
request {
   url '/bar'
   method GET()
}
response {
    status OK()
    body(
       bar: "bar"
    }
}

您无法为同一个请求生成两个不同的响应。这就是您可以正确打包契约然后从 stubsPerConsumer 特性中获益的原因。

在生产者端,消费者可以有一个仅包含与它们相关的契约的文件夹。通过将 stubrunner.stubs-per-consumer 标志设置为 true,我们不再注册所有存根,而仅注册与消费者应用程序名称对应的存根。换句话说,我们扫描每个存根的路径,如果该路径中包含一个子文件夹的名称是消费者,则仅注册该存根。

foo 生产者端,契约如下所示:

.
└── contracts
    ├── bar-consumer
    │   ├── bookReturnedForBar.groovy
    │   └── shouldCallBar.groovy
    └── foo-consumer
        ├── bookReturnedForFoo.groovy
        └── shouldCallFoo.groovy

bar-consumer 消费者可以将 spring.application.namestubrunner.consumer-name 设置为 bar-consumer。或者,您可以按如下方式设置测试:

Unresolved directive in stub-runner-stubs-per-consumer.adoc - include::{stubrunner_core_path}/src/test/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/StubRunnerStubsPerConsumerSpec.groovy[]
...
}

然后,仅允许引用在名称中包含 bar-consumer 的路径下注册的存根(即来自 src/test/resources/contracts/bar-consumer/some/contracts/…​ 文件夹的存根)。

您也可以显式设置使用者名称,如下所示:

Unresolved directive in stub-runner-stubs-per-consumer.adoc - include::{stubrunner_core_path}/src/test/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/StubRunnerStubsPerConsumerWithConsumerNameSpec.groovy[]
...
}

然后,仅允许引用名称中包含 foo-consumer 的路径下注册的 stub(即那些位于 src/test/resources/contracts/foo-consumer/some/contracts/…​ 文件夹中的 stub)。

欲了解此更改背后的原因的更多信息,请参阅 issue 224