对于最新的稳定版本,请使用 spring-cloud-contract 4.2.0spring-doc.cadn.net.cn

常见顶级元素

描述

您可以添加description添加到您的合同中。描述是任意文本。这 下面的代码显示了一个示例:spring-doc.cadn.net.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
"""
}

名字

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

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

以下示例演示如何向协定添加名称:spring-doc.cadn.net.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 配置或设置ignoredproperty 的 intent 属性。以下内容 示例展示了如何做到这一点:spring-doc.cadn.net.cn

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

正在进行的合同

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

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

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

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

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

从文件传递值

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

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

进一步假设您的 Contract 如下:spring-doc.cadn.net.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
		}
	}
}

Further assume that the JSON files are as follows:spring-doc.cadn.net.cn

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

When test or stub generation takes place, the contents of the request.json and response.json files are passed to the body of a request or a response. The name of the file needs to be a file in a location relative to the folder in which the contract resides.spring-doc.cadn.net.cn

If you need to pass the contents of a file in binary form, you can use the fileAsBytes method in the coded DSL or a bodyFromFileAsBytes field in YAML.spring-doc.cadn.net.cn

The following example shows how to pass the contents of binary files:spring-doc.cadn.net.cn

Groovy
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
		}
	}
}
You should use this approach whenever you want to work with binary payloads, both for HTTP and messaging.

Metadata

You can add metadata to your contract. Via the metadata you can pass in configuration to extensions. Below you can find an example of using the wiremock key. Its value is a map whose key is stubMapping and value being WireMock’s StubMapping object. Spring Cloud Contract is able to patch parts of your generated stub mapping with your custom code. You may want to do that in order to add webhooks, custom delays or integrate with third party WireMock extensions.spring-doc.cadn.net.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
  }
}"""))
}

In the following sections you can find examples of the supported metadata entries.spring-doc.cadn.net.cn

Contracts for HTTP

Spring Cloud Contract lets you verify applications that use REST or HTTP as a means of communication. Spring Cloud Contract verifies that, for a request that matches the criteria from the request part of the contract, the server provides a response that is in keeping with the response part of the contract. Subsequently, the contracts are used to generate WireMock stubs that, for any request matching the provided criteria, provide a suitable response.spring-doc.cadn.net.cn