共通のトップレベル要素
説明
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
"""
}
名前
契約の名前を指定できます。should register a user
という名前を指定するとします。これを行うと、自動生成されたテストの名前は validate_should_register_a_user
になります。また、WireMock スタブ内のスタブの名前は should_register_a_user.json
です。
生成されたテストをコンパイルできなくなる文字が名前に含まれていないことを確認する必要があります。また、複数の契約に同じ名前を指定すると、自動生成されたテストはコンパイルに失敗し、生成されたスタブが相互にオーバーライドされることに注意してください。 |
次の例は、契約に名前を追加する方法を示しています。
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"
}
契約の無視
契約を無視したい場合は、プラグイン設定で無視される契約の値を設定するか、契約自体に 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
}
failOnInProgress
Spring Cloud Contract プラグインプロパティの値を設定して、進行中の契約が少なくとも 1 つソース内に残っているときにビルドが中断されるようにすることができます。
ファイルから値を渡す
バージョン 1.2.0
以降では、ファイルから値を渡すことができます。プロジェクトに次のリソースがあると仮定します。
└── src
└── test
└── resources
└── contracts
├── readFromFile.groovy
├── request.json
└── response.json
さらに、契約が次のようになっていると仮定します。
/*
* 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"
}
テストまたはスタブの生成が行われると、request.json
ファイルおよび response.json
ファイルの内容がリクエストまたはレスポンスの本文に渡されます。ファイルの名前は、契約が存在するフォルダーに相対的な場所にあるファイルである必要があります。
ファイルの内容をバイナリ形式で渡す必要がある場合は、コード化された DSL の fileAsBytes
メソッド、または YAML の 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 とメッセージングの両方でバイナリペイロードを操作する場合は、常にこのアプローチを使用する必要があります。 |
メタデータ
metadata
を契約に追加できます。メタデータを介して、拡張機能に設定を渡すことができます。以下に、wiremock
キーの使用例を示します。その値は、キーが stubMapping
で、値が WireMock の StubMapping
オブジェクトであるマップです。Spring Cloud Contract は、生成されたスタブマッピングの一部にカスタムコードをパッチできます。Webhook やカスタム遅延を追加したり、サードパーティの WireMock 拡張機能と統合したりするために、これを行うことができます。
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
}
}"""))
}
次のセクションでは、サポートされているメタデータエントリの例を示します。