Done
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
[[getting-started-cdc]]
|
||||
= Step-by-step Guide to Consumer Driven Contracts (CDC) with Contracts on the Producer Side
|
||||
|
||||
include::partial$_attributes.adoc[]
|
||||
|
||||
Consider an example of fraud detection and the loan issuance process. The business
|
||||
scenario is such that we want to issue loans to people but do not want them to steal from
|
||||
us. The current implementation of our system grants loans to everybody.
|
||||
@@ -33,21 +35,23 @@ in the producer's repository.
|
||||
If you use the SNAPSHOT, Milestone, or Release Candidate versions, you need to add the
|
||||
following section to your build:
|
||||
|
||||
====
|
||||
[tabs]
|
||||
======
|
||||
Maven::
|
||||
+
|
||||
[source,xml,indent=0,subs="verbatim,attributes",role="primary"]
|
||||
.Maven
|
||||
----
|
||||
include:../:{introduction_url}/samples/standalone/dsl/http-server/pom.xml[tags=repos,indent=0]
|
||||
include::{samples_path}/standalone/dsl/http-server/pom.xml[tags=repos,indent=0]
|
||||
----
|
||||
======
|
||||
////
|
||||
|
||||
////
|
||||
[source,groovy,indent=0,subs="verbatim,attributes",role="secondary"]
|
||||
.Gradle
|
||||
----
|
||||
include:../:{introduction_url}/samples/standalone/dsl/http-server/build.gradle[tags=deps_repos,indent=0]
|
||||
include::{samples_path}/standalone/dsl/http-server/build.gradle[tags=deps_repos,indent=0]
|
||||
----
|
||||
====
|
||||
|
||||
For simplicity, we use the following acronyms:
|
||||
|
||||
@@ -109,12 +113,10 @@ We start with the loan issuance flow, which the following UML diagram shows:
|
||||
The following listing shows a test that we might use to check whether a loan amount is too
|
||||
large:
|
||||
|
||||
====
|
||||
[source,groovy,indent=0]
|
||||
----
|
||||
include:../:{introduction_url}/samples/standalone/dsl/http-client/src/test/java/com/example/loan/LoanApplicationServiceTests.java[tags=client_tdd,indent=0]
|
||||
include::{samples_path}/standalone/dsl/http-client/src/test/java/com/example/loan/LoanApplicationServiceTests.java[tags=client_tdd,indent=0]
|
||||
----
|
||||
====
|
||||
|
||||
Assume that you have written a test of your new feature. If a loan application for a big
|
||||
amount is received, the system should reject that loan application with some description.
|
||||
@@ -127,12 +129,10 @@ that you need to send the request containing the ID of the client and the amount
|
||||
client wants to borrow. You want to send it to the `/fraudcheck` URL by using the `PUT` method.
|
||||
To do so, you might use code similar to the following:
|
||||
|
||||
====
|
||||
[source,groovy,indent=0]
|
||||
----
|
||||
include:../:{introduction_url}/samples/standalone/dsl/http-client/src/main/java/com/example/loan/LoanApplicationService.java[tags=client_call_server,indent=0]
|
||||
include::{samples_path}/standalone/dsl/http-client/src/main/java/com/example/loan/LoanApplicationService.java[tags=client_call_server,indent=0]
|
||||
----
|
||||
====
|
||||
|
||||
For simplicity, the port of the Fraud Detection service is set to `8080`, and the
|
||||
application runs on `8090`.
|
||||
@@ -146,12 +146,10 @@ NOTE: If you start the test at this point, it breaks, because no service current
|
||||
You can start by playing around with the server side contract. To do so, you must first
|
||||
clone it, by running the following command:
|
||||
|
||||
====
|
||||
[source,bash,indent=0]
|
||||
----
|
||||
$ git clone https://your-git-server.com/server-side.git local-http-server-repo
|
||||
----
|
||||
====
|
||||
|
||||
[[getting-started-cdc-consumer-define]]
|
||||
=== Define the Contract Locally in the Repository of the Fraud Detection Service
|
||||
@@ -164,21 +162,16 @@ is important because the producer's test base class name references that folder.
|
||||
|
||||
The following example shows our contract, in both Groovy and YAML:
|
||||
|
||||
====
|
||||
[source,groovy,indent=0,role="primary"]
|
||||
.groovy
|
||||
----
|
||||
include:../:{introduction_url}/samples/standalone/dsl/http-server/src/test/resources/contracts/fraud/shouldMarkClientAsFraud.groovy[]
|
||||
include::{samples_path}/standalone/dsl/http-server/src/test/resources/contracts/fraud/shouldMarkClientAsFraud.groovy[]
|
||||
----
|
||||
////
|
||||
|
||||
////
|
||||
[source,yaml,indent=0,role="secondary"]
|
||||
.yaml
|
||||
----
|
||||
include:../:{introduction_url}/samples/standalone/dsl/http-server/src/test/resources/contracts/yml/fraud/shouldMarkClientAsFraud.yml[]
|
||||
include::{samples_path}/standalone/dsl/http-server/src/test/resources/contracts/yml/fraud/shouldMarkClientAsFraud.yml[]
|
||||
----
|
||||
====
|
||||
|
||||
The YML contract is quite straightforward. However, when you take a look at the contract
|
||||
written with a statically typed Groovy DSL, you might wonder what the
|
||||
@@ -196,7 +189,7 @@ The previously shown contract is an agreement between two sides that:
|
||||
|
||||
* If an HTTP request is sent with all of:
|
||||
** A `PUT` method on the `/fraudcheck` endpoint
|
||||
** A JSON body with a `client.id` that matches the regular expression `[0-9]{10}` and
|
||||
** A JSON body with a `client.id` that matches the regular expression `[0-9]\{10}` and
|
||||
`loanAmount` equal to `99999`
|
||||
** A `Content-Type` header with a value of `application/vnd.fraud.v1+json`
|
||||
* Then an HTTP response is sent to the consumer that
|
||||
@@ -214,21 +207,17 @@ install the stubs locally.
|
||||
We can add either a Maven or a Gradle plugin. In this example, we show how to add Maven.
|
||||
First, we add the `Spring Cloud Contract` BOM, as the following example shows:
|
||||
|
||||
====
|
||||
[source,xml,indent=0]
|
||||
----
|
||||
include:../:{introduction_url}/samples/standalone/dsl/http-server/pom.xml[tags=contract_bom,indent=0]
|
||||
include::{samples_path}/standalone/dsl/http-server/pom.xml[tags=contract_bom,indent=0]
|
||||
----
|
||||
====
|
||||
|
||||
Next, add the `Spring Cloud Contract Verifier` Maven plugin, as the following example shows:
|
||||
|
||||
====
|
||||
[source,xml,indent=0]
|
||||
----
|
||||
include:../:{introduction_url}/samples/standalone/dsl/http-server/pom.xml[tags=contract_maven_plugin,indent=0]
|
||||
include::{samples_path}/standalone/dsl/http-server/pom.xml[tags=contract_maven_plugin,indent=0]
|
||||
----
|
||||
====
|
||||
|
||||
Since the plugin was added, you get the `Spring Cloud Contract Verifier` features, which,
|
||||
from the provided contracts:
|
||||
@@ -239,17 +228,14 @@ from the provided contracts:
|
||||
You do not want to generate tests, since you, as the consumer, want only to play with the
|
||||
stubs. You need to skip the test generation and invokation. To do so, run the following commands:
|
||||
|
||||
====
|
||||
[source,bash,indent=0]
|
||||
----
|
||||
$ cd local-http-server-repo
|
||||
$ ./mvnw clean install -DskipTests
|
||||
----
|
||||
====
|
||||
|
||||
Once you run those commands, you should you see something like the following content in the logs:
|
||||
|
||||
====
|
||||
[source,bash,indent=0]
|
||||
----
|
||||
[INFO] --- spring-cloud-contract-maven-plugin:1.0.0.BUILD-SNAPSHOT:generateStubs (default-generateStubs) @ http-server ---
|
||||
@@ -265,16 +251,13 @@ Once you run those commands, you should you see something like the following con
|
||||
[INFO] Installing /some/path/http-server/pom.xml to /path/to/your/.m2/repository/com/example/http-server/0.0.1-SNAPSHOT/http-server-0.0.1-SNAPSHOT.pom
|
||||
[INFO] Installing /some/path/http-server/target/http-server-0.0.1-SNAPSHOT-stubs.jar to /path/to/your/.m2/repository/com/example/http-server/0.0.1-SNAPSHOT/http-server-0.0.1-SNAPSHOT-stubs.jar
|
||||
----
|
||||
====
|
||||
|
||||
The following line is extremely important:
|
||||
|
||||
====
|
||||
[source,bash,indent=0]
|
||||
----
|
||||
[INFO] Installing /some/path/http-server/target/http-server-0.0.1-SNAPSHOT-stubs.jar to /path/to/your/.m2/repository/com/example/http-server/0.0.1-SNAPSHOT/http-server-0.0.1-SNAPSHOT-stubs.jar
|
||||
----
|
||||
====
|
||||
|
||||
It confirms that the stubs of the `http-server` have been installed in the local
|
||||
repository.
|
||||
@@ -288,39 +271,32 @@ Application service`):
|
||||
|
||||
. Add the `Spring Cloud Contract` BOM, as follows:
|
||||
+
|
||||
====
|
||||
[source,xml,indent=0]
|
||||
----
|
||||
include:../:{introduction_url}/samples/standalone/dsl/http-client/pom.xml[tags=contract_bom,indent=0]
|
||||
include::{samples_path}/standalone/dsl/http-client/pom.xml[tags=contract_bom,indent=0]
|
||||
----
|
||||
====
|
||||
|
||||
. Add the dependency to `Spring Cloud Contract Stub Runner`, as follows:
|
||||
+
|
||||
====
|
||||
[source,xml,indent=0]
|
||||
----
|
||||
include:../:{introduction_url}/samples/standalone/dsl/http-client/pom.xml[tags=stub_runner,indent=0]
|
||||
include::{samples_path}/standalone/dsl/http-client/pom.xml[tags=stub_runner,indent=0]
|
||||
----
|
||||
====
|
||||
|
||||
. Annotate your test class with `@AutoConfigureStubRunner`. In the annotation, provide the
|
||||
`group-id` and `artifact-id` for the Stub Runner to download the stubs of your
|
||||
collaborators.
|
||||
+
|
||||
====
|
||||
[source,groovy,indent=0]
|
||||
----
|
||||
include:../:{introduction_url}/samples/standalone/dsl/http-client/src/test/java/com/example/loan/LoanApplicationServiceTests.java[tags=autoconfigure_stubrunner,indent=0]
|
||||
include::{samples_path}/standalone/dsl/http-client/src/test/java/com/example/loan/LoanApplicationServiceTests.java[tags=autoconfigure_stubrunner,indent=0]
|
||||
----
|
||||
====
|
||||
|
||||
. (Optional) Because you are playing with the collaborators offline, you
|
||||
can also provide the offline work switch (`StubRunnerProperties.StubsMode.LOCAL`).
|
||||
|
||||
Now, when you run your tests, you see something like the following output in the logs:
|
||||
|
||||
====
|
||||
[source,bash,indent=0]
|
||||
----
|
||||
2016-07-19 14:22:25.403 INFO 41050 --- [ main] o.s.c.c.stubrunner.AetherStubDownloader : Desired version is + - will try to resolve the latest version
|
||||
@@ -331,7 +307,6 @@ Now, when you run your tests, you see something like the following output in the
|
||||
2016-07-19 14:22:25.475 INFO 41050 --- [ main] o.s.c.c.stubrunner.AetherStubDownloader : Unpacked file to [/var/folders/0p/xwq47sq106x1_g3dtv6qfm940000gq/T/contracts100276532569594265]
|
||||
2016-07-19 14:22:27.737 INFO 41050 --- [ main] o.s.c.c.stubrunner.StubRunnerExecutor : All stubs are now running RunningStubs [namesAndPorts={com.example:http-server:0.0.1-SNAPSHOT:stubs=8080}]
|
||||
----
|
||||
====
|
||||
|
||||
This output means that Stub Runner has found your stubs and started a server for your application
|
||||
with a group ID of `com.example` and an artifact ID of `http-server` with version `0.0.1-SNAPSHOT` of
|
||||
@@ -384,42 +359,34 @@ The following UML diagram shows the fraud detection flow:
|
||||
|
||||
As a reminder, the following listing shows the initial implementation:
|
||||
|
||||
====
|
||||
[source,java,indent=0]
|
||||
----
|
||||
include:../:{introduction_url}/samples/standalone/dsl/http-server/src/main/java/com/example/fraud/FraudDetectionController.java[tags=server_api,indent=0]
|
||||
include:../:{introduction_url}/samples/standalone/dsl/http-server/src/main/java/com/example/fraud/FraudDetectionController.java[tags=initial_impl,indent=0]
|
||||
include::{samples_path}/standalone/dsl/http-server/src/main/java/com/example/fraud/FraudDetectionController.java[tags=server_api,indent=0]
|
||||
include::{samples_path}/standalone/dsl/http-server/src/main/java/com/example/fraud/FraudDetectionController.java[tags=initial_impl,indent=0]
|
||||
}
|
||||
----
|
||||
====
|
||||
|
||||
Then you can run the following commands:
|
||||
|
||||
====
|
||||
[source,bash,indent=0]
|
||||
----
|
||||
$ git checkout -b contract-change-pr master
|
||||
$ git pull https://your-git-server.com/server-side-fork.git contract-change-pr
|
||||
----
|
||||
====
|
||||
|
||||
You must add the dependencies needed by the autogenerated tests, as follows:
|
||||
|
||||
====
|
||||
[source,xml,indent=0]
|
||||
----
|
||||
include:../:{introduction_url}/samples/standalone/dsl/http-server/pom.xml[tags=verifier_test_dependencies,indent=0]
|
||||
include::{samples_path}/standalone/dsl/http-server/pom.xml[tags=verifier_test_dependencies,indent=0]
|
||||
----
|
||||
====
|
||||
|
||||
In the configuration of the Maven plugin, you must pass the `packageWithBaseClasses` property, as follows:
|
||||
|
||||
====
|
||||
[source,xml,indent=0]
|
||||
----
|
||||
include:../:{introduction_url}/samples/standalone/dsl/http-server/pom.xml[tags=contract_maven_plugin,indent=0]
|
||||
include::{samples_path}/standalone/dsl/http-server/pom.xml[tags=contract_maven_plugin,indent=0]
|
||||
----
|
||||
====
|
||||
|
||||
IMPORTANT: This example uses "`convention-based`" naming by setting the
|
||||
`packageWithBaseClasses` property. Doing so means that the two last packages combine to
|
||||
@@ -433,16 +400,13 @@ or whatever is necessary. In this case, you should use https://github.com/rest-a
|
||||
start the server side `FraudDetectionController`. The following listing shows the
|
||||
`FraudBase` class:
|
||||
|
||||
====
|
||||
[source,java,indent=0]
|
||||
----
|
||||
include:../:{introduction_url}/samples/standalone/dsl/http-server/src/test/java/com/example/fraud/FraudBase.java[]
|
||||
include::{samples_path}/standalone/dsl/http-server/src/test/java/com/example/fraud/FraudBase.java[]
|
||||
----
|
||||
====
|
||||
|
||||
Now, if you run the `./mvnw clean install`, you get something like the following output:
|
||||
|
||||
====
|
||||
[source,bash,indent=0]
|
||||
----
|
||||
Results :
|
||||
@@ -450,13 +414,11 @@ Results :
|
||||
Tests in error:
|
||||
ContractVerifierTest.validate_shouldMarkClientAsFraud:32 » IllegalState Parsed...
|
||||
----
|
||||
====
|
||||
|
||||
This error occurs because you have a new contract from which a test was generated, and it
|
||||
failed since you have not implemented the feature. The auto-generated test would look
|
||||
like the following test method:
|
||||
|
||||
====
|
||||
[source,java,indent=0]
|
||||
----
|
||||
@Test
|
||||
@@ -479,7 +441,6 @@ public void validate_shouldMarkClientAsFraud() throws Exception {
|
||||
assertThatJson(parsedJson).field("['rejection.reason']").isEqualTo("Amount too high");
|
||||
}
|
||||
----
|
||||
====
|
||||
|
||||
If you used the Groovy DSL, you can see that all the `producer()` parts of the Contract that were present in the
|
||||
`value(consumer(...), producer(...))` blocks got injected into the test.
|
||||
@@ -497,15 +458,13 @@ in the response. In other words, you have the `red` part of `red`, `green`, and
|
||||
Because you know the expected input and expected output, you can write the missing
|
||||
implementation as follows:
|
||||
|
||||
====
|
||||
[source,java,indent=0]
|
||||
----
|
||||
include:../:{introduction_url}/samples/standalone/dsl/http-server/src/main/java/com/example/fraud/FraudDetectionController.java[tags=server_api,indent=0]
|
||||
include:../:{introduction_url}/samples/standalone/dsl/http-server/src/main/java/com/example/fraud/FraudDetectionController.java[tags=new_impl,indent=0]
|
||||
include:../:{introduction_url}/samples/standalone/dsl/http-server/src/main/java/com/example/fraud/FraudDetectionController.java[tags=initial_impl,indent=0]
|
||||
include::{samples_path}/standalone/dsl/http-server/src/main/java/com/example/fraud/FraudDetectionController.java[tags=server_api,indent=0]
|
||||
include::{samples_path}/standalone/dsl/http-server/src/main/java/com/example/fraud/FraudDetectionController.java[tags=new_impl,indent=0]
|
||||
include::{samples_path}/standalone/dsl/http-server/src/main/java/com/example/fraud/FraudDetectionController.java[tags=initial_impl,indent=0]
|
||||
}
|
||||
----
|
||||
====
|
||||
|
||||
When you run `./mvnw clean install` again, the tests pass. Since the Spring Cloud
|
||||
Contract Verifier plugin adds the tests to the `generated-test-sources`, you can
|
||||
@@ -517,14 +476,12 @@ actually run those tests from your IDE.
|
||||
Once you finish your work, you can deploy your changes. To do so, you must first merge the
|
||||
branch by running the following commands:
|
||||
|
||||
====
|
||||
[source,bash,indent=0]
|
||||
----
|
||||
$ git checkout master
|
||||
$ git merge --no-ff contract-change-pr
|
||||
$ git push origin master
|
||||
----
|
||||
====
|
||||
|
||||
Your CI might run a command such as `./mvnw clean deploy`, which would publish both the
|
||||
application and the stub artifacts.
|
||||
@@ -560,13 +517,11 @@ The following UML diagram shows the final state of the process:
|
||||
|
||||
The following commands show one way to merge a branch into master with Git:
|
||||
|
||||
====
|
||||
[source,bash,indent=0]
|
||||
----
|
||||
$ git checkout master
|
||||
$ git merge --no-ff contract-change-pr
|
||||
----
|
||||
====
|
||||
|
||||
[[getting-started-cdc-consumer-final-online]]
|
||||
=== Working Online
|
||||
@@ -577,12 +532,10 @@ side are automatically downloaded from Nexus/Artifactory. You can set the value
|
||||
`stubsMode` to `REMOTE`. The following code shows an example of
|
||||
achieving the same thing by changing the properties:
|
||||
|
||||
====
|
||||
[source,yaml,indent=0]
|
||||
----
|
||||
include:../:{introduction_url}/samples/standalone/dsl/http-client/src/test/resources/application-test-repo.yaml[]
|
||||
include::{samples_path}/standalone/dsl/http-client/src/test/resources/application-test-repo.yaml[]
|
||||
----
|
||||
====
|
||||
|
||||
That's it. You have finished the tutorial.
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
[[getting-started-first-application]]
|
||||
= Developing Your First Spring Cloud Contract-based Application
|
||||
|
||||
include::partial$_attributes.adoc[]
|
||||
|
||||
This brief tour walks through using Spring Cloud Contract. It consists of the following topics:
|
||||
|
||||
* xref:getting-started/first-application.adoc#getting-started-first-application-producer[On the Producer Side]
|
||||
@@ -13,7 +15,23 @@ For the sake of this example, the `Stub Storage` is Nexus/Artifactory.
|
||||
|
||||
The following UML diagram shows the relationship of the parts of Spring Cloud Contract:
|
||||
|
||||
image::getting-started-three-second.png[Getting started first application]
|
||||
[plantuml, getting-started-three-second, png]
|
||||
----
|
||||
"API Producer"->"API Producer": add Spring Cloud \nContract (SCC) plugin
|
||||
"API Producer"->"API Producer": add SCC Verifier dependency
|
||||
"API Producer"->"API Producer": define contracts
|
||||
"API Producer"->"Build": run build
|
||||
"Build"->"SCC Plugin": generate \ntests, stubs and stubs \nartifact (e.g. stubs-jar)
|
||||
"Build"->"Stub Storage": upload contracts \nand stubs and the project arifact
|
||||
"Build"->"API Producer": Build successful
|
||||
"API Consumer"->"API Consumer": add SCC Stub Runner \ndependency
|
||||
"API Consumer"->"API Consumer": write a SCC Stub Runner \nbased contract test
|
||||
"SCC Stub Runner"->"Stub Storage": test asks for [API Producer] stubs
|
||||
"Stub Storage"->"SCC Stub Runner": fetch the [API Producer] stubs
|
||||
"SCC Stub Runner"->"SCC Stub Runner": run in memory\n HTTP server stubs
|
||||
"API Consumer"->"SCC Stub Runner": send a request \nto the HTTP server stub
|
||||
"SCC Stub Runner"->"API Consumer": communication is correct
|
||||
----
|
||||
|
||||
[[getting-started-first-application-producer]]
|
||||
== On the Producer Side
|
||||
@@ -21,17 +39,14 @@ image::getting-started-three-second.png[Getting started first application]
|
||||
To start working with `Spring Cloud Contract`, you can add the Spring Cloud Contract Verifier
|
||||
dependency and plugin to your build file, as the following example shows:
|
||||
|
||||
====
|
||||
[source,xml,indent=0]
|
||||
----
|
||||
include:../:{introduction_url}/samples/standalone/dsl/http-server/pom.xml[tags=verifier_test_dependencies,indent=0]
|
||||
include::{samples_path}/standalone/dsl/http-server/pom.xml[tags=verifier_test_dependencies,indent=0]
|
||||
----
|
||||
====
|
||||
|
||||
The following listing shows how to add the plugin, which should go in the build/plugins
|
||||
portion of the file:
|
||||
|
||||
====
|
||||
[source,xml,indent=0]
|
||||
----
|
||||
<plugin>
|
||||
@@ -41,7 +56,6 @@ portion of the file:
|
||||
<extensions>true</extensions>
|
||||
</plugin>
|
||||
----
|
||||
====
|
||||
|
||||
[TIP]
|
||||
====
|
||||
@@ -64,9 +78,11 @@ For the HTTP stubs, a contract defines what kind of response should be returned
|
||||
given request (taking into account the HTTP methods, URLs, headers, status codes, and so
|
||||
on). The following example shows an HTTP stub contract in both Groovy and YAML:
|
||||
|
||||
====
|
||||
[tabs]
|
||||
======
|
||||
groovy::
|
||||
+
|
||||
[source,groovy,indent=0,role="primary"]
|
||||
.groovy
|
||||
----
|
||||
package contracts
|
||||
|
||||
@@ -95,8 +111,9 @@ org.springframework.cloud.contract.spec.Contract.make {
|
||||
}
|
||||
----
|
||||
|
||||
yaml::
|
||||
+
|
||||
[source,yaml,indent=0,role="secondary"]
|
||||
.yaml
|
||||
----
|
||||
request:
|
||||
method: PUT
|
||||
@@ -119,7 +136,7 @@ response:
|
||||
headers:
|
||||
Content-Type: application/json;charset=UTF-8
|
||||
----
|
||||
====
|
||||
======
|
||||
|
||||
If you need to use messaging, you can define:
|
||||
|
||||
@@ -130,19 +147,22 @@ was sent, the message body, and the header).
|
||||
|
||||
The following example shows a Camel messaging contract:
|
||||
|
||||
====
|
||||
[tabs]
|
||||
======
|
||||
groovy::
|
||||
+
|
||||
[source,groovy,indent=0,role="primary"]
|
||||
.groovy
|
||||
----
|
||||
include:../:{verifier_core_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MessagingMethodBodyBuilderSpec.groovy[tags=trigger_method_dsl]
|
||||
include::{verifier_root_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MessagingMethodBodyBuilderSpec.groovy[tags=trigger_method_dsl]
|
||||
----
|
||||
|
||||
yaml::
|
||||
+
|
||||
[source,yaml,indent=0,role="secondary"]
|
||||
.yaml
|
||||
----
|
||||
include:../:{verifier_core_path}/src/test/resources/yml/contract_message_scenario1.yml[indent=0]
|
||||
include::{verifier_root_path}/src/test/resources/yml/contract_message_scenario1.yml[indent=0]
|
||||
----
|
||||
====
|
||||
======
|
||||
|
||||
Running `./mvnw clean install` automatically generates tests that verify the application
|
||||
compliance with the added contracts. By default, the generated tests are under
|
||||
@@ -163,9 +183,11 @@ of the other frameworks, add its library to your classpath.
|
||||
|
||||
The following listing shows samples for all frameworks:
|
||||
|
||||
====
|
||||
[tabs]
|
||||
======
|
||||
mockmvc::
|
||||
+
|
||||
[source,java,indent=0,role="primary"]
|
||||
.mockmvc
|
||||
----
|
||||
@Test
|
||||
public void validate_shouldMarkClientAsFraud() throws Exception {
|
||||
@@ -188,8 +210,9 @@ public void validate_shouldMarkClientAsFraud() throws Exception {
|
||||
}
|
||||
----
|
||||
|
||||
jaxrs::
|
||||
+
|
||||
[source,java,indent=0,role="secondary"]
|
||||
.jaxrs
|
||||
----
|
||||
@SuppressWarnings("rawtypes")
|
||||
public class FooTest {
|
||||
@@ -225,8 +248,9 @@ public class FooTest {
|
||||
}
|
||||
----
|
||||
|
||||
webtestclient::
|
||||
+
|
||||
[source,java,indent=0,role="secondary"]
|
||||
.webtestclient
|
||||
----
|
||||
@Test
|
||||
public void validate_shouldRejectABeerIfTooYoung() throws Exception {
|
||||
@@ -247,7 +271,7 @@ public class FooTest {
|
||||
assertThatJson(parsedJson).field("['status']").isEqualTo("NOT_OK");
|
||||
}
|
||||
----
|
||||
====
|
||||
======
|
||||
|
||||
As the implementation of the functionalities described by the contracts is not yet
|
||||
present, the tests fail.
|
||||
@@ -260,7 +284,6 @@ contain all the setup necessary information needed to run them (for example,
|
||||
|
||||
The following example, from `pom.xml`, shows how to specify the base test class:
|
||||
|
||||
====
|
||||
[source,xml,indent=0]
|
||||
----
|
||||
<build>
|
||||
@@ -283,11 +306,9 @@ The following example, from `pom.xml`, shows how to specify the base test class:
|
||||
----
|
||||
<1> The `baseClassForTests` element lets you specify your base test class. It must be a child
|
||||
of a `configuration` element within `spring-cloud-contract-maven-plugin`.
|
||||
====
|
||||
|
||||
The following example shows a minimal (but functional) base test class:
|
||||
|
||||
====
|
||||
[source,java, indent=0]
|
||||
----
|
||||
package com.example.contractTest;
|
||||
@@ -304,7 +325,6 @@ public class BaseTestClass {
|
||||
}
|
||||
}
|
||||
----
|
||||
====
|
||||
|
||||
This minimal class really is all you need to get your tests to work. It serves as a
|
||||
starting place to which the automatically generated tests attach.
|
||||
@@ -312,7 +332,6 @@ starting place to which the automatically generated tests attach.
|
||||
Now we can move on to the implementation. For that, we first need a data class, which we
|
||||
then use in our controller. The following listing shows the data class:
|
||||
|
||||
====
|
||||
[source,java, indent=0]
|
||||
----
|
||||
package com.example.Test;
|
||||
@@ -343,7 +362,6 @@ public class LoanRequest {
|
||||
}
|
||||
}
|
||||
----
|
||||
====
|
||||
|
||||
The preceding class provides an object in which we can store the parameters. Because the
|
||||
client ID in the contract is called `client.id`, we need to use the
|
||||
@@ -351,7 +369,6 @@ client ID in the contract is called `client.id`, we need to use the
|
||||
|
||||
Now we can move along to the controller, which the following listing shows:
|
||||
|
||||
====
|
||||
[source,java, indent=0]
|
||||
----
|
||||
package com.example.docTest;
|
||||
@@ -379,7 +396,6 @@ public class FraudController {
|
||||
<3> If it is too much, we return the JSON (created with a simple string here) that the
|
||||
test expects.
|
||||
<4> If we had a test to catch when the amount is allowable, we could match it to this output.
|
||||
====
|
||||
|
||||
The `FraudController` is about as simple as things get. You can do much more, including
|
||||
logging, validating the client ID, and so on.
|
||||
@@ -389,7 +405,6 @@ application and the stub artifacts are built and installed in the local Maven re
|
||||
Information about installing the stubs jar to the local repository appears in the logs, as
|
||||
the following example shows:
|
||||
|
||||
====
|
||||
[source,bash,indent=0]
|
||||
----
|
||||
[INFO] --- spring-cloud-contract-maven-plugin:1.0.0.BUILD-SNAPSHOT:generateStubs (default-generateStubs) @ http-server ---
|
||||
@@ -405,7 +420,6 @@ the following example shows:
|
||||
[INFO] Installing /some/path/http-server/pom.xml to /path/to/your/.m2/repository/com/example/http-server/0.0.1-SNAPSHOT/http-server-0.0.1-SNAPSHOT.pom
|
||||
[INFO] Installing /some/path/http-server/target/http-server-0.0.1-SNAPSHOT-stubs.jar to /path/to/your/.m2/repository/com/example/http-server/0.0.1-SNAPSHOT/http-server-0.0.1-SNAPSHOT-stubs.jar
|
||||
----
|
||||
====
|
||||
|
||||
You can now merge the changes and publish both the application and the stub artifacts
|
||||
in an online repository.
|
||||
@@ -418,12 +432,10 @@ WireMock instance or messaging route that simulates the actual service.
|
||||
|
||||
To get started, add the dependency to `Spring Cloud Contract Stub Runner`, as follows:
|
||||
|
||||
====
|
||||
[source,xml,indent=0]
|
||||
----
|
||||
include:../:{introduction_url}/samples/standalone/dsl/http-client/pom.xml[tags=stub_runner,indent=0]
|
||||
include::{samples_path}/standalone/dsl/http-client/pom.xml[tags=stub_runner,indent=0]
|
||||
----
|
||||
====
|
||||
|
||||
You can get the Producer-side stubs installed in your Maven repository in either of two
|
||||
ways:
|
||||
@@ -431,13 +443,11 @@ ways:
|
||||
* By checking out the Producer side repository and adding contracts and generating the
|
||||
stubs by running the following commands:
|
||||
+
|
||||
====
|
||||
[source,bash,indent=0]
|
||||
----
|
||||
$ cd local-http-server-repo
|
||||
$ ./mvnw clean install -DskipTests
|
||||
----
|
||||
====
|
||||
NOTE: The tests are skipped because the Producer-side contract implementation is not yet
|
||||
in place, so the automatically-generated contract tests fail.
|
||||
|
||||
@@ -445,18 +455,15 @@ in place, so the automatically-generated contract tests fail.
|
||||
pass the stub artifact IDs and artifact repository URL as `Spring Cloud Contract Stub
|
||||
Runner` properties, as the following example shows:
|
||||
+
|
||||
====
|
||||
[source,yaml,indent=0]
|
||||
----
|
||||
include:../:{introduction_url}/samples/standalone/dsl/http-client/src/test/resources/application-test-repo.yaml[]
|
||||
include::{samples_path}/standalone/dsl/http-client/src/test/resources/application-test-repo.yaml[]
|
||||
----
|
||||
====
|
||||
|
||||
Now you can annotate your test class with `@AutoConfigureStubRunner`. In the annotation,
|
||||
provide the `group-id` and `artifact-id` for `Spring Cloud Contract Stub Runner` to run
|
||||
the collaborators' stubs for you, as the following example shows:
|
||||
|
||||
====
|
||||
[source,java, indent=0]
|
||||
----
|
||||
@RunWith(SpringRunner.class)
|
||||
@@ -467,7 +474,6 @@ public class LoanApplicationServiceTests {
|
||||
. . .
|
||||
}
|
||||
----
|
||||
====
|
||||
|
||||
TIP: Use the `REMOTE` `stubsMode` when downloading stubs from an online repository and
|
||||
`LOCAL` for offline work.
|
||||
@@ -476,7 +482,6 @@ In your integration test, you can receive stubbed versions of HTTP responses or
|
||||
that are expected to be emitted by the collaborator service. You can see entries similar
|
||||
to the following in the build logs:
|
||||
|
||||
====
|
||||
[source,bash,indent=0]
|
||||
----
|
||||
2016-07-19 14:22:25.403 INFO 41050 --- [ main] o.s.c.c.stubrunner.AetherStubDownloader : Desired version is + - will try to resolve the latest version
|
||||
@@ -487,5 +492,4 @@ to the following in the build logs:
|
||||
2016-07-19 14:22:25.475 INFO 41050 --- [ main] o.s.c.c.stubrunner.AetherStubDownloader : Unpacked file to [/var/folders/0p/xwq47sq106x1_g3dtv6qfm940000gq/T/contracts100276532569594265]
|
||||
2016-07-19 14:22:27.737 INFO 41050 --- [ main] o.s.c.c.stubrunner.StubRunnerExecutor : All stubs are now running RunningStubs [namesAndPorts={com.example:http-server:0.0.1-SNAPSHOT:stubs=8080}]
|
||||
----
|
||||
====
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
[[getting-started-introducing-spring-cloud-contract]]
|
||||
= Introducing Spring Cloud Contract
|
||||
|
||||
include::partial$_attributes.adoc[]
|
||||
|
||||
Spring Cloud Contract moves TDD to the level of software architecture.
|
||||
It lets you perform consumer-driven and producer-driven contract testing.
|
||||
|
||||
@@ -106,21 +108,23 @@ amount it wants to borrow from us. You also want to send it to the `/fraudcheck`
|
||||
the `PUT` method. The following listing shows a contract to check whether a client should
|
||||
be marked as a fraud in both Groovy and YAML:
|
||||
|
||||
====
|
||||
[tabs]
|
||||
======
|
||||
groovy::
|
||||
+
|
||||
[source,groovy,indent=0,role="primary"]
|
||||
.groovy
|
||||
----
|
||||
include:../:{introduction_url}/samples/standalone/dsl/http-server/src/test/resources/contracts/fraud/shouldMarkClientAsFraud.groovy[]
|
||||
include::{samples_path}/standalone/dsl/http-server/src/test/resources/contracts/fraud/shouldMarkClientAsFraud.groovy[]
|
||||
----
|
||||
======
|
||||
////
|
||||
|
||||
////
|
||||
[source,yaml,indent=0,role="secondary"]
|
||||
.yaml
|
||||
----
|
||||
include:../:{introduction_url}/samples/standalone/dsl/http-server/src/test/resources/contracts/yml/fraud/shouldMarkClientAsFraud.yml[]
|
||||
include::{samples_path}/standalone/dsl/http-server/src/test/resources/contracts/yml/fraud/shouldMarkClientAsFraud.yml[]
|
||||
----
|
||||
====
|
||||
|
||||
IMPORTANT: It is expected that contracts are coming from a **trusted source**. You should never download nor interact with contracts coming from untrusted locations.
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
[[getting-started-three-second-tour]]
|
||||
= A Three-second Tour
|
||||
|
||||
include::partial$_attributes.adoc[]
|
||||
|
||||
This very brief tour walks through using Spring Cloud Contract. It consists of the
|
||||
following topics:
|
||||
|
||||
@@ -40,17 +42,14 @@ expressed in either Groovy DSL or YAML to the contracts directory, which is set
|
||||
Then you can add the Spring Cloud Contract Verifier dependency and plugin to your build file, as
|
||||
the following example shows:
|
||||
|
||||
====
|
||||
[source,xml,indent=0]
|
||||
----
|
||||
include:../:{introduction_url}/samples/standalone/dsl/http-server/pom.xml[tags=verifier_test_dependencies,indent=0]
|
||||
include::{samples_path}/standalone/dsl/http-server/pom.xml[tags=verifier_test_dependencies,indent=0]
|
||||
----
|
||||
====
|
||||
|
||||
The following listing shows how to add the plugin, which should go in the build/plugins
|
||||
portion of the file:
|
||||
|
||||
====
|
||||
[source,xml,indent=0]
|
||||
----
|
||||
<plugin>
|
||||
@@ -60,7 +59,6 @@ portion of the file:
|
||||
<extensions>true</extensions>
|
||||
</plugin>
|
||||
----
|
||||
====
|
||||
|
||||
Running `./mvnw clean install` automatically generates tests that verify the application
|
||||
compliance with the added contracts. By default, the tests get generated under
|
||||
@@ -77,7 +75,6 @@ controller setup or messaging test setup).
|
||||
|
||||
The following example, from `pom.xml`, shows how to specify the base test class:
|
||||
|
||||
====
|
||||
[source,xml,indent=0]
|
||||
----
|
||||
<build>
|
||||
@@ -100,7 +97,6 @@ The following example, from `pom.xml`, shows how to specify the base test class:
|
||||
----
|
||||
<1> The `baseClassForTests` element lets you specify your base test class. It must be a child
|
||||
of a `configuration` element within `spring-cloud-contract-maven-plugin`.
|
||||
====
|
||||
|
||||
Once the implementation and the test base class are in place, the tests pass, and both the
|
||||
application and the stub artifacts are built and installed in the local Maven repository.
|
||||
@@ -116,12 +112,10 @@ WireMock instance or messaging route that simulates the actual service.
|
||||
To do so, add the dependency to `Spring Cloud Contract Stub Runner`, as the
|
||||
following example shows:
|
||||
|
||||
====
|
||||
[source,xml,indent=0]
|
||||
----
|
||||
include:../:{introduction_url}/samples/standalone/dsl/http-client/pom.xml[tags=stub_runner,indent=0]
|
||||
include::{samples_path}/standalone/dsl/http-client/pom.xml[tags=stub_runner,indent=0]
|
||||
----
|
||||
====
|
||||
|
||||
You can get the Producer-side stubs installed in your Maven repository in either of two
|
||||
ways:
|
||||
@@ -129,13 +123,11 @@ ways:
|
||||
* By checking out the Producer side repository and adding contracts and generating the stubs
|
||||
by running the following commands:
|
||||
+
|
||||
====
|
||||
[source,bash,indent=0]
|
||||
----
|
||||
$ cd local-http-server-repo
|
||||
$ ./mvnw clean install -DskipTests
|
||||
----
|
||||
====
|
||||
|
||||
TIP: The tests are being skipped because the producer-side contract implementation is not
|
||||
in place yet, so the automatically-generated contract tests fail.
|
||||
@@ -144,18 +136,15 @@ in place yet, so the automatically-generated contract tests fail.
|
||||
pass the stub artifact IDs and artifact repository URL as `Spring Cloud Contract
|
||||
Stub Runner` properties, as the following example shows:
|
||||
+
|
||||
====
|
||||
[source,yaml,indent=0]
|
||||
----
|
||||
include:../:{introduction_url}/samples/standalone/dsl/http-client/src/test/resources/application-test-repo.yaml[]
|
||||
include::{samples_path}/standalone/dsl/http-client/src/test/resources/application-test-repo.yaml[]
|
||||
----
|
||||
====
|
||||
|
||||
Now you can annotate your test class with `@AutoConfigureStubRunner`. In the annotation,
|
||||
provide the `group-id` and `artifact-id` values for `Spring Cloud Contract Stub Runner` to
|
||||
run the collaborators' stubs for you, as the following example shows:
|
||||
|
||||
====
|
||||
[source,java, indent=0]
|
||||
----
|
||||
@RunWith(SpringRunner.class)
|
||||
@@ -166,7 +155,6 @@ public class LoanApplicationServiceTests {
|
||||
. . .
|
||||
}
|
||||
----
|
||||
====
|
||||
|
||||
TIP: Use the `REMOTE` `stubsMode` when downloading stubs from an online repository and
|
||||
`LOCAL` for offline work.
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
[[getting-started-whats-next]]
|
||||
= Next Steps
|
||||
|
||||
include::partial$_attributes.adoc[]
|
||||
|
||||
Hopefully, this section provided some of the {project-full-name} basics and got you on your way
|
||||
to writing your own applications. If you are a task-oriented type of developer, you might
|
||||
want to jump over to https://spring.io and check out some
|
||||
|
||||
Reference in New Issue
Block a user