此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 spring-cloud-contract 4.1.5spring-doc.cn

常见顶级元素

描述

您可以将 添加到您的合同中。描述是任意文本。这 下面的代码显示了一个示例:descriptionspring-doc.cn

槽的
			org.springframework.cloud.contract.spec.Contract.make {
				description('''
given:
	An input
when:
	Sth happens
then:
	Output
''')
			}
YAML
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)
Java
Contract.make(c -> {
	c.description("Some description");
}));
Kotlin
contract {
	description = """
given:
	An input
when:
	Sth happens
then:
	Output
"""
}

名字

您可以为合同提供名称。假设您提供以下名称:。如果这样做,则自动生成的测试的名称为 。此外,WireMock 存根中的存根名称为 .should register a uservalidate_should_register_a_usershould_register_a_user.jsonspring-doc.cn

您必须确保名称不包含任何使 生成的测试未编译。另外,请记住,如果您为 多个 Contract,则自动生成的测试无法编译,并且生成的存根 相互覆盖。

以下示例演示如何向协定添加名称:spring-doc.cn

槽的
org.springframework.cloud.contract.spec.Contract.make {
	name("some_special_name")
}
YAML
name: some name
Java
Contract.make(c -> {
	c.name("some name");
}));
Kotlin
contract {
	name = "some_special_name"
}

忽略合同

如果要忽略合约,可以在 plugin 配置或在 Contract 本身上设置 property 的 intent 来设置属性。以下内容 示例展示了如何做到这一点:ignoredspring-doc.cn

槽的
org.springframework.cloud.contract.spec.Contract.make {
	ignored()
}
YAML
ignored: true
Java
Contract.make(c -> {
	c.ignored();
}));
Kotlin
contract {
	ignored = true
}

正在进行的合同

正在进行的合同不会在生产者端生成测试,但允许生成存根。spring-doc.cn

请谨慎使用此功能,因为它可能会导致误报,因为您会生成存根供使用者使用,而实际上没有实施。

如果要设置正在进行的合同,请执行以下操作 示例展示了如何做到这一点:spring-doc.cn

槽的
org.springframework.cloud.contract.spec.Contract.make {
	inProgress()
}
YAML
inProgress: true
Java
Contract.make(c -> {
	c.inProgress();
}));
Kotlin
contract {
	inProgress = true
}

您可以设置 Spring Cloud Contract 插件属性的值,以确保当源中至少有一个正在进行的 Contract 时,您的构建会中断。failOnInProgressspring-doc.cn

从文件传递值

从 version 开始,您可以从文件中传递值。假设您拥有 项目中的以下资源:1.2.0spring-doc.cn

└── src
    └── test
        └── resources
            └── contracts
                ├── readFromFile.groovy
                ├── request.json
                └── response.json

进一步假设您的 Contract 如下:spring-doc.cn

槽的
/*
 * 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())
		}
	}
}
YAML
request:
  method: GET
  url: /foo
  bodyFromFile: request.json
response:
  status: 200
  bodyFromFile: response.json
Java
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"));
			});
		}));
	}

}
Kotlin
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 文件如下所示:spring-doc.cn

request.json
{
  "status": "REQUEST"
}
response.json
{
  "status": "RESPONSE"
}

当 test 或 stub 生成时,和 文件的内容将传递给正文 请求或响应。文件的名称必须是某个位置中的文件 相对于合同所在的文件夹。request.jsonresponse.jsonspring-doc.cn

如果需要以二进制形式传递文件的内容, 您可以使用编码的 DSL 或 YAML 中的字段中的方法。fileAsBytesbodyFromFileAsBytesspring-doc.cn

以下示例演示如何传递二进制文件的内容:spring-doc.cn

槽的
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())
		}
	}
}
YAML
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
Java
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());
				});
			});
		}));
	}

}
Kotlin
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 扩展集成。metadatawiremockstubMappingStubMappingspring-doc.cn

Java
Contract.make(c -> {
	c.metadata(MetadataUtil.map()
		.entry("wiremock", ContractVerifierUtil.map()
			.entry("stubMapping", "{ \"response\" : { \"fixedDelayMilliseconds\" : 2000 } }")));
}));
kotlin
contract {
	metadata("wiremock" to ("stubmapping" to """
{
  "response" : {
	"fixedDelayMilliseconds": 2000
  }
}"""))
}

在以下部分中,您可以找到支持的元数据条目的示例。spring-doc.cn

HTTP 协定

Spring Cloud Contract 允许您验证使用 REST 或 HTTP 作为 通讯方式。Spring Cloud Contract 验证,对于与 criteria 中,服务器会提供一个响应,该响应位于 遵守合同的一部分。随后,这些合约被用来 生成 WireMock 存根,对于与提供条件匹配的任何请求,该存根提供 适当的回应。requestresponsespring-doc.cn