此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 spring-cloud-contract 4.1.5! |
常见顶级元素
描述
您可以将 添加到您的合同中。描述是任意文本。这
下面的代码显示了一个示例:description
org.springframework.cloud.contract.spec.Contract.make {
description('''
given:
An input
when:
Sth happens
then:
Output
''')
}
description: Some description
name: some name
priority: 8
ignored: true
request:
url: /foo
queryParameters:
a: b
b: c
method: PUT
headers:
foo: bar
fooReq: baz
body:
foo: bar
matchers:
body:
- path: $.foo
type: by_regex
value: bar
headers:
- key: foo
regex: bar
response:
status: 200
headers:
foo2: bar
foo3: foo33
fooRes: baz
body:
foo2: bar
foo3: baz
nullValue: null
matchers:
body:
- path: $.foo2
type: by_regex
value: bar
- path: $.foo3
type: by_command
value: executeMe($it)
- path: $.nullValue
type: by_null
value: null
headers:
- key: foo2
regex: bar
- key: foo3
command: andMeToo($it)
Contract.make(c -> {
c.description("Some description");
}));
contract {
description = """
given:
An input
when:
Sth happens
then:
Output
"""
}
名字
您可以为合同提供名称。假设您提供以下名称:。如果这样做,则自动生成的测试的名称为 。此外,WireMock 存根中的存根名称为 .should register a user
validate_should_register_a_user
should_register_a_user.json
您必须确保名称不包含任何使 生成的测试未编译。另外,请记住,如果您为 多个 Contract,则自动生成的测试无法编译,并且生成的存根 相互覆盖。 |
以下示例演示如何向协定添加名称:
org.springframework.cloud.contract.spec.Contract.make {
name("some_special_name")
}
name: some name
Contract.make(c -> {
c.name("some name");
}));
contract {
name = "some_special_name"
}
忽略合同
如果要忽略合约,可以在
plugin 配置或在 Contract 本身上设置 property 的 intent 来设置属性。以下内容
示例展示了如何做到这一点:ignored
org.springframework.cloud.contract.spec.Contract.make {
ignored()
}
ignored: true
Contract.make(c -> {
c.ignored();
}));
contract {
ignored = true
}
正在进行的合同
正在进行的合同不会在生产者端生成测试,但允许生成存根。
请谨慎使用此功能,因为它可能会导致误报,因为您会生成存根供使用者使用,而实际上没有实施。 |
如果要设置正在进行的合同,请执行以下操作 示例展示了如何做到这一点:
org.springframework.cloud.contract.spec.Contract.make {
inProgress()
}
inProgress: true
Contract.make(c -> {
c.inProgress();
}));
contract {
inProgress = true
}
您可以设置 Spring Cloud Contract 插件属性的值,以确保当源中至少有一个正在进行的 Contract 时,您的构建会中断。failOnInProgress
从文件传递值
从 version 开始,您可以从文件中传递值。假设您拥有
项目中的以下资源:1.2.0
└── src
└── test
└── resources
└── contracts
├── readFromFile.groovy
├── request.json
└── response.json
进一步假设您的 Contract 如下:
/*
* Copyright 2013-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.springframework.cloud.contract.spec.Contract
Contract.make {
request {
method('PUT')
headers {
contentType(applicationJson())
}
body(file("request.json"))
url("/1")
}
response {
status OK()
body(file("response.json"))
headers {
contentType(applicationJson())
}
}
}
request:
method: GET
url: /foo
bodyFromFile: request.json
response:
status: 200
bodyFromFile: response.json
import java.util.Collection;
import java.util.Collections;
import java.util.function.Supplier;
import org.springframework.cloud.contract.spec.Contract;
class contract_rest_from_file implements Supplier<Collection<Contract>> {
@Override
public Collection<Contract> get() {
return Collections.singletonList(Contract.make(c -> {
c.request(r -> {
r.url("/foo");
r.method(r.GET());
r.body(r.file("request.json"));
});
c.response(r -> {
r.status(r.OK());
r.body(r.file("response.json"));
});
}));
}
}
import org.springframework.cloud.contract.spec.ContractDsl.Companion.contract
contract {
request {
url = url("/1")
method = PUT
headers {
contentType = APPLICATION_JSON
}
body = bodyFromFile("request.json")
}
response {
status = OK
body = bodyFromFile("response.json")
headers {
contentType = APPLICATION_JSON
}
}
}
进一步假设 JSON 文件如下所示:
{
"status": "REQUEST"
}
{
"status": "RESPONSE"
}
当 test 或 stub 生成时,和 文件的内容将传递给正文
请求或响应。文件的名称必须是某个位置中的文件
相对于合同所在的文件夹。request.json
response.json
如果需要以二进制形式传递文件的内容,
您可以使用编码的 DSL 或 YAML 中的字段中的方法。fileAsBytes
bodyFromFileAsBytes
以下示例演示如何传递二进制文件的内容:
import org.springframework.cloud.contract.spec.Contract
Contract.make {
request {
url("/1")
method(PUT())
headers {
contentType(applicationOctetStream())
}
body(fileAsBytes("request.pdf"))
}
response {
status 200
body(fileAsBytes("response.pdf"))
headers {
contentType(applicationOctetStream())
}
}
}
request:
url: /1
method: PUT
headers:
Content-Type: application/octet-stream
bodyFromFileAsBytes: request.pdf
response:
status: 200
bodyFromFileAsBytes: response.pdf
headers:
Content-Type: application/octet-stream
import java.util.Collection;
import java.util.Collections;
import java.util.function.Supplier;
import org.springframework.cloud.contract.spec.Contract;
class contract_rest_from_pdf implements Supplier<Collection<Contract>> {
@Override
public Collection<Contract> get() {
return Collections.singletonList(Contract.make(c -> {
c.request(r -> {
r.url("/1");
r.method(r.PUT());
r.body(r.fileAsBytes("request.pdf"));
r.headers(h -> {
h.contentType(h.applicationOctetStream());
});
});
c.response(r -> {
r.status(r.OK());
r.body(r.fileAsBytes("response.pdf"));
r.headers(h -> {
h.contentType(h.applicationOctetStream());
});
});
}));
}
}
import org.springframework.cloud.contract.spec.ContractDsl.Companion.contract
contract {
request {
url = url("/1")
method = PUT
headers {
contentType = APPLICATION_OCTET_STREAM
}
body = bodyFromFileAsBytes("contracts/request.pdf")
}
response {
status = OK
body = bodyFromFileAsBytes("contracts/response.pdf")
headers {
contentType = APPLICATION_OCTET_STREAM
}
}
}
每当您想要使用二进制有效负载时,都应该使用此方法。 适用于 HTTP 和消息传递。 |
元数据
您可以添加到您的合同中。通过元数据,您可以将配置传递给扩展。您可以在下面找到
使用密钥的示例。它的值是一个 map,其 key 是 WireMock 的对象,value 是 WireMock 的对象。Spring Cloud Contract 能够
使用自定义代码修补生成的存根映射的各个部分。您可能希望这样做以添加 webhook,自定义
延迟或与第三方 WireMock 扩展集成。metadata
wiremock
stubMapping
StubMapping
Contract.make(c -> {
c.metadata(MetadataUtil.map()
.entry("wiremock", ContractVerifierUtil.map()
.entry("stubMapping", "{ \"response\" : { \"fixedDelayMilliseconds\" : 2000 } }")));
}));
contract {
metadata("wiremock" to ("stubmapping" to """
{
"response" : {
"fixedDelayMilliseconds": 2000
}
}"""))
}
在以下部分中,您可以找到支持的元数据条目的示例。
HTTP 协定
Spring Cloud Contract 允许您验证使用 REST 或 HTTP 作为
通讯方式。Spring Cloud Contract 验证,对于与
criteria 中,服务器会提供一个响应,该响应位于
遵守合同的一部分。随后,这些合约被用来
生成 WireMock 存根,对于与提供条件匹配的任何请求,该存根提供
适当的回应。request
response