Updated docs
This commit is contained in:
@@ -21,6 +21,7 @@
|
||||
:verifier_root_path: {core_path}/spring-cloud-contract-verifier
|
||||
:contract_spec_path: {core_path}/specs/spring-cloud-contract-spec-java
|
||||
:contract_spec_tests_path: {core_path}/specs/spring-cloud-contract-spec
|
||||
:contract_kotlin_spec_path: {core_path}/specs/spring-cloud-contract-spec-kotlin
|
||||
:samples_path: {core_path}/samples
|
||||
:verifier_core_path: {verifier_root_path}
|
||||
:stubrunner_core_path: {core_path}/spring-cloud-contract-stub-runner
|
||||
|
||||
@@ -7,6 +7,7 @@ Spring Cloud Contract supports the DSLs written in the following languages:
|
||||
* Groovy
|
||||
* YAML
|
||||
* Java
|
||||
* Kotlin
|
||||
|
||||
TIP: Spring Cloud Contract supports defining multiple contracts in a single file.
|
||||
|
||||
@@ -30,6 +31,12 @@ include::{verifier_core_path}/src/test/resources/yml/contract_rest.yml[indent=0]
|
||||
----
|
||||
include::{verifier_core_path}/src/test/resources/contractsToCompile/contract_rest.java[tags=class,indent=0]
|
||||
----
|
||||
|
||||
[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"]
|
||||
.kotlin
|
||||
----
|
||||
include::{verifier_core_path}/src/test/resources/kotlin/contract_rest.kts[tags=class,indent=0]
|
||||
----
|
||||
====
|
||||
|
||||
[TIP]
|
||||
@@ -89,6 +96,17 @@ contracts {
|
||||
----
|
||||
====
|
||||
|
||||
[[contract-kotlin]]
|
||||
=== Contract DSL in Kotlin
|
||||
|
||||
To get started with writing contracts in Kotlin you would need to start with a (newly created) Kotlin Script file (.kts).
|
||||
Just like the with the Java DSL you can put your contracts in any directory of your choice.
|
||||
The Maven and Gradle plugins will look at the `src/test/resources/contracts` directory by default.
|
||||
|
||||
IMPORTANT: Remember that, inside the Kotlin Script file, you have to provide the fully qualified name to the `ContractDSL` class.
|
||||
Generally you would use its contract function like this: `org.springframework.cloud.contract.spec.ContractDsl.contract { ... }`.
|
||||
You can also provide an import to the `contract` function (`import org.springframework.cloud.contract.spec.ContractDsl.Companion.contract`) and then call `contract { ... }`.
|
||||
|
||||
[[contract-limitations]]
|
||||
=== Limitations
|
||||
|
||||
@@ -136,6 +154,12 @@ include::{verifier_core_path}/src/test/resources/yml/contract_rest.yml[indent=0]
|
||||
----
|
||||
include::{verifier_core_path}/src/test/resources/contractsToCompile/contract_rest_with_tags.java[tags=description,indent=0]
|
||||
----
|
||||
|
||||
[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"]
|
||||
.kotlin
|
||||
----
|
||||
include::{contract_kotlin_spec_path}/src/test/kotlin/org/springframework/cloud/contract/spec/ContractTests.kt[tags=description,indent=0]
|
||||
----
|
||||
====
|
||||
|
||||
[[contract-dsl-name]]
|
||||
@@ -171,6 +195,12 @@ include::{verifier_core_path}/src/test/resources/yml/contract.yml[tags=name,inde
|
||||
----
|
||||
include::{verifier_core_path}/src/test/resources/contractsToCompile/contract_rest_with_tags.java[tags=name,indent=0]
|
||||
----
|
||||
|
||||
[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"]
|
||||
.kotlin
|
||||
----
|
||||
include::{contract_kotlin_spec_path}/src/test/kotlin/org/springframework/cloud/contract/spec/ContractTests.kt[tags=name,indent=0]
|
||||
----
|
||||
====
|
||||
|
||||
[[contract-dsl-ignoring-contracts]]
|
||||
@@ -198,6 +228,12 @@ include::{verifier_core_path}/src/test/resources/yml/contract.yml[tags=ignored,i
|
||||
----
|
||||
include::{verifier_core_path}/src/test/resources/contractsToCompile/contract_rest_with_tags.java[tags=ignored,indent=0]
|
||||
----
|
||||
|
||||
[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"]
|
||||
.kotlin
|
||||
----
|
||||
include::{contract_kotlin_spec_path}/src/test/kotlin/org/springframework/cloud/contract/spec/ContractTests.kt[tags=ignored,indent=0]
|
||||
----
|
||||
====
|
||||
|
||||
[[contract-dsl-in-progress]]
|
||||
@@ -228,6 +264,12 @@ include::{verifier_core_path}/src/test/resources/yml/contract.yml[tags=in_progre
|
||||
----
|
||||
include::{verifier_core_path}/src/test/resources/contractsToCompile/contract_rest_with_tags.java[tags=in_progress,indent=0]
|
||||
----
|
||||
|
||||
[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"]
|
||||
.kotlin
|
||||
----
|
||||
include::{contract_kotlin_spec_path}/src/test/kotlin/org/springframework/cloud/contract/spec/ContractTests.kt[tags=in_progress,indent=0]
|
||||
----
|
||||
====
|
||||
|
||||
You can set the value of the `failOnInProgress` Spring Cloud Contract plugin property to ensure that your build will break when at least one contract in progress remains in your sources.
|
||||
@@ -269,6 +311,12 @@ include::{verifier_core_path}/src/test/resources/yml/contract_from_file.yml[inde
|
||||
----
|
||||
include::{verifier_core_path}/src/test/resources/contractsToCompile/contract_rest_from_file.java[tags=class,indent=0]
|
||||
----
|
||||
|
||||
[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"]
|
||||
.kotlin
|
||||
----
|
||||
include::{verifier_core_path}/src/test/resources/kotlin/readFromFile.kts[tags=class,indent=0]
|
||||
----
|
||||
====
|
||||
|
||||
Further assume that the JSON files is as follows:
|
||||
@@ -314,6 +362,12 @@ include::{verifier_core_path}/src/test/resources/yml/contract_pdf.yml[indent=0]
|
||||
----
|
||||
include::{verifier_core_path}/src/test/resources/contractsToCompile/contract_rest_from_pdf.java[tags=class,indent=0]
|
||||
----
|
||||
|
||||
[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"]
|
||||
.kotlin
|
||||
----
|
||||
include::{contract_kotlin_spec_path}/src/test/resources/contracts/shouldWorkWithBinaryPayload.kts[tags=class,indent=0]
|
||||
----
|
||||
====
|
||||
|
||||
IMPORTANT: You should use this approach whenever you want to work with binary payloads,
|
||||
@@ -362,6 +416,12 @@ include::{verifier_core_path}/src/test/resources/yml/contract.yml[tags=response,
|
||||
----
|
||||
include::{verifier_core_path}/src/test/resources/contractsToCompile/contract_docs_examples.java[tags=http_dsl,indent=0]
|
||||
----
|
||||
|
||||
[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"]
|
||||
.kotlin
|
||||
----
|
||||
include::{verifier_core_path}/src/test/resources/kotlin/contract_docs_examples.kts[tags=http_dsl,indent=0]
|
||||
----
|
||||
====
|
||||
|
||||
IMPORTANT: If you want to make your contract have a higher priority,
|
||||
@@ -394,6 +454,12 @@ include::{verifier_core_path}/src/test/resources/yml/contract.yml[tags=request_o
|
||||
----
|
||||
include::{verifier_core_path}/src/test/resources/contractsToCompile/contract_docs_examples.java[tags=request,indent=0]
|
||||
----
|
||||
|
||||
[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"]
|
||||
.kotlin
|
||||
----
|
||||
include::{verifier_core_path}/src/test/resources/kotlin/contract_docs_examples.kts[tags=request,indent=0]
|
||||
----
|
||||
====
|
||||
|
||||
You can specify an absolute rather than a relative `url`, but using `urlPath` is
|
||||
@@ -419,6 +485,12 @@ include::{verifier_core_path}/src/test/resources/yml/contract_rest_with_path.yml
|
||||
----
|
||||
include::{verifier_core_path}/src/test/resources/contractsToCompile/contract_docs_examples.java[tags=url,indent=0]
|
||||
----
|
||||
|
||||
[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"]
|
||||
.kotlin
|
||||
----
|
||||
include::{verifier_core_path}/src/test/resources/kotlin/contract_docs_examples.kts[tags=url,indent=0]
|
||||
----
|
||||
====
|
||||
|
||||
`request` may contain query parameters, as the following example (which uses `urlPath`) shows:
|
||||
@@ -443,6 +515,12 @@ include::{verifier_core_path}/src/test/resources/yml/contract.yml[tags=query_par
|
||||
----
|
||||
include::{verifier_core_path}/src/test/resources/contractsToCompile/contract_docs_examples.java[tags=urlpath,indent=0]
|
||||
----
|
||||
|
||||
[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"]
|
||||
.kotlin
|
||||
----
|
||||
include::{verifier_core_path}/src/test/resources/kotlin/contract_docs_examples.kts[tags=urlpath,indent=0]
|
||||
----
|
||||
====
|
||||
|
||||
`request` can contain additional request headers, as the following example shows:
|
||||
@@ -467,6 +545,12 @@ include::{verifier_core_path}/src/test/resources/yml/contract.yml[tags=headers,i
|
||||
----
|
||||
include::{verifier_core_path}/src/test/resources/contractsToCompile/contract_docs_examples.java[tags=headers,indent=0]
|
||||
----
|
||||
|
||||
[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"]
|
||||
.kotlin
|
||||
----
|
||||
include::{verifier_core_path}/src/test/resources/kotlin/contract_docs_examples.kts[tags=headers,indent=0]
|
||||
----
|
||||
====
|
||||
|
||||
`request` may contain additional request cookies, as the following example shows:
|
||||
@@ -491,6 +575,12 @@ include::{verifier_core_path}/src/test/resources/yml/contract.yml[tags=cookies,i
|
||||
----
|
||||
include::{verifier_core_path}/src/test/resources/contractsToCompile/contract_docs_examples.java[tags=cookies,indent=0]
|
||||
----
|
||||
|
||||
[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"]
|
||||
.kotlin
|
||||
----
|
||||
include::{verifier_core_path}/src/test/resources/kotlin/contract_docs_examples.kts[tags=cookies,indent=0]
|
||||
----
|
||||
====
|
||||
|
||||
`request` may contain a request body, as the following example shows:
|
||||
@@ -515,6 +605,12 @@ include::{verifier_core_path}/src/test/resources/yml/contract.yml[tags=body,inde
|
||||
----
|
||||
include::{verifier_core_path}/src/test/resources/contractsToCompile/contract_docs_examples.java[tags=body,indent=0]
|
||||
----
|
||||
|
||||
[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"]
|
||||
.kotlin
|
||||
----
|
||||
include::{verifier_core_path}/src/test/resources/kotlin/contract_docs_examples.kts[tags=body,indent=0]
|
||||
----
|
||||
====
|
||||
|
||||
`request` can contain multipart elements. To include multipart elements, use the
|
||||
@@ -538,6 +634,12 @@ include::{verifier_core_path}/src/test/resources/yml/contract_multipart.yml[inde
|
||||
----
|
||||
include::{verifier_core_path}/src/test/resources/contractsToCompile/contract_multipart.java[tags=class,indent=0]
|
||||
----
|
||||
|
||||
[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"]
|
||||
.kotlin
|
||||
----
|
||||
include::{verifier_core_path}/src/test/resources/kotlin/multipart.kts[tags=class,indent=0]
|
||||
----
|
||||
====
|
||||
|
||||
In the preceding example, we define parameters in either of two ways:
|
||||
@@ -618,6 +720,12 @@ include::{verifier_core_path}/src/test/resources/yml/contract.yml[tags=response_
|
||||
----
|
||||
include::{verifier_core_path}/src/test/resources/contractsToCompile/contract_docs_examples.java[tags=response,indent=0]
|
||||
----
|
||||
|
||||
[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"]
|
||||
.kotlin
|
||||
----
|
||||
include::{verifier_core_path}/src/test/resources/kotlin/contract_docs_examples.kts[tags=response,indent=0]
|
||||
----
|
||||
====
|
||||
|
||||
Besides status, the response may contain headers, cookies, and a body, which are
|
||||
@@ -706,6 +814,12 @@ include::{verifier_core_path}/src/test/groovy/org/springframework/cloud/contract
|
||||
----
|
||||
include::{verifier_core_path}/src/test/resources/contractsToCompile/contract_docs_examples.java[tags=regex,indent=0]
|
||||
----
|
||||
|
||||
[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"]
|
||||
.kotlin
|
||||
----
|
||||
include::{verifier_core_path}/src/test/resources/kotlin/contract_docs_examples.kts[tags=regex,indent=0]
|
||||
----
|
||||
====
|
||||
|
||||
You can also provide only one side of the communication with a regular expression. If you
|
||||
@@ -744,13 +858,22 @@ All of those methods start with the `any` prefix, as follows:
|
||||
include::{contract_spec_path}/src/main/java/org/springframework/cloud/contract/spec/internal/RegexCreatingProperty.java[tags=regex_creating_props,indent=0]
|
||||
----
|
||||
|
||||
The following example shows how you can reference those methods (example for Groovy DSL):
|
||||
The following example shows how you can reference those methods:
|
||||
|
||||
[source,groovy,indent=0]
|
||||
====
|
||||
[source,groovy,indent=0,role="primary"]
|
||||
.groovy
|
||||
----
|
||||
include::{verifier_core_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MessagingMethodBodyBuilderSpec.groovy[tags=regex_creating_props,indent=0]
|
||||
----
|
||||
|
||||
[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"]
|
||||
.kotlin
|
||||
----
|
||||
include::{verifier_core_path}/src/test/resources/kotlin/contract_docs_examples.kts[tags=regex_creating_props,indent=0]
|
||||
----
|
||||
====
|
||||
|
||||
[[contract-dsl-regex-limitations]]
|
||||
===== Limitations
|
||||
|
||||
@@ -788,6 +911,12 @@ include::{verifier_core_path}/src/test/groovy/org/springframework/cloud/contract
|
||||
----
|
||||
include::{verifier_core_path}/src/test/resources/contractsToCompile/contract_docs_examples.java[tags=optionals,indent=0]
|
||||
----
|
||||
|
||||
[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"]
|
||||
.kotlin
|
||||
----
|
||||
include::{verifier_core_path}/src/test/resources/kotlin/contract_docs_examples.kts[tags=optionals,indent=0]
|
||||
----
|
||||
====
|
||||
|
||||
By wrapping a part of the body with the `optional()` method, you create a regular
|
||||
@@ -833,6 +962,12 @@ include::{verifier_core_path}/src/test/groovy/org/springframework/cloud/contract
|
||||
----
|
||||
include::{verifier_core_path}/src/test/resources/contractsToCompile/contract_docs_examples.java[tags=method,indent=0]
|
||||
----
|
||||
|
||||
[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"]
|
||||
.kotlin
|
||||
----
|
||||
include::{verifier_core_path}/src/test/resources/kotlin/contract_docs_examples.kts[tags=method,indent=0]
|
||||
----
|
||||
====
|
||||
|
||||
The following code shows the base class portion of the test case:
|
||||
@@ -978,6 +1113,37 @@ class shouldReturnStatsForAUser implements Supplier<Contract> {
|
||||
|
||||
}
|
||||
----
|
||||
|
||||
[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"]
|
||||
.kotlin
|
||||
----
|
||||
package contracts.beer.rest
|
||||
|
||||
import org.springframework.cloud.contract.spec.ContractDsl.Companion.contract
|
||||
|
||||
contract {
|
||||
request {
|
||||
method = method("POST")
|
||||
url = url("/stats")
|
||||
body(mapOf(
|
||||
"name" to anyAlphaUnicode
|
||||
))
|
||||
headers {
|
||||
contentType = APPLICATION_JSON
|
||||
}
|
||||
}
|
||||
response {
|
||||
status = OK
|
||||
body(mapOf(
|
||||
"text" to "Don't worry ${fromRequest().body("$.name")} thanks for your interested in drinking beer",
|
||||
"quantity" to v(c(5), p(anyNumber))
|
||||
))
|
||||
headers {
|
||||
contentType = fromRequest().header(CONTENT_TYPE)
|
||||
}
|
||||
}
|
||||
}
|
||||
----
|
||||
====
|
||||
|
||||
Running a JUnit test generation leads to a test that resembles the following example:
|
||||
@@ -1401,6 +1567,22 @@ class contract implements Supplier<Collection<Contract>> {
|
||||
|
||||
}
|
||||
----
|
||||
|
||||
[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"]
|
||||
.kotlin
|
||||
----
|
||||
import org.springframework.cloud.contract.spec.ContractDsl.Companion.contract
|
||||
|
||||
contract {
|
||||
request {
|
||||
// ...
|
||||
}
|
||||
response {
|
||||
async = true
|
||||
// ...
|
||||
}
|
||||
}
|
||||
----
|
||||
====
|
||||
|
||||
You can also use the `fixedDelayMilliseconds` method or property to add delay to your stubs.
|
||||
@@ -1450,6 +1632,22 @@ class contract implements Supplier<Collection<Contract>> {
|
||||
|
||||
}
|
||||
----
|
||||
|
||||
[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"]
|
||||
.kotlin
|
||||
----
|
||||
import org.springframework.cloud.contract.spec.ContractDsl.Companion.contract
|
||||
|
||||
contract {
|
||||
request {
|
||||
// ...
|
||||
}
|
||||
response {
|
||||
delay = fixedMilliseconds(1000)
|
||||
// ...
|
||||
}
|
||||
}
|
||||
----
|
||||
====
|
||||
|
||||
[[contract-dsl-xml]]
|
||||
@@ -1482,6 +1680,12 @@ include::{verifier_core_path}/src/test/resources/yml/contract_rest_xml.yml
|
||||
----
|
||||
include::{verifier_core_path}/src/test/resources/contractsToCompile/contract_xml.java[tags=class,indent=0]
|
||||
----
|
||||
|
||||
[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"]
|
||||
.kotlin
|
||||
----
|
||||
include::{verifier_core_path}/src/test/resources/kotlin/contract_xml.kts[tags=class,indent=0]
|
||||
----
|
||||
====
|
||||
|
||||
The following example shows an automatically generated test for XML in the response body:
|
||||
@@ -1555,6 +1759,25 @@ class contract implements Supplier<Collection<Contract>> {
|
||||
|
||||
}
|
||||
----
|
||||
|
||||
[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"]
|
||||
.kotlin
|
||||
----
|
||||
import org.springframework.cloud.contract.spec.ContractDsl.Companion.contract
|
||||
|
||||
arrayOf(
|
||||
contract {
|
||||
name("should post a user")
|
||||
// ...
|
||||
},
|
||||
contract {
|
||||
// ...
|
||||
},
|
||||
contract {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
----
|
||||
====
|
||||
|
||||
In the preceding example, one contract has the `name` field and the other does not. This
|
||||
|
||||
Reference in New Issue
Block a user