diff --git a/README.adoc b/README.adoc
index c9fcc0cf37..09a0ee07f8 100644
--- a/README.adoc
+++ b/README.adoc
@@ -590,7 +590,7 @@ org.springframework.cloud.contract.spec.Contract.make {
loanAmount: 99999
])
headers { // (5)
- header('Content-Type', 'application/vnd.fraud.v1+json')
+ contentType("application/vnd.fraud.v1+json")
}
}
response { // (6)
@@ -600,10 +600,7 @@ org.springframework.cloud.contract.spec.Contract.make {
rejectionReason: "Amount too high"
])
headers { // (9)
- header('Content-Type': value(
- producer(regex('application/vnd.fraud.v1.json.*')),
- consumer('application/vnd.fraud.v1+json'))
- )
+ contentType("application/vnd.fraud.v1+json")
}
}
}
@@ -871,16 +868,28 @@ That's because all the generated tests will extend that class. Over there you ca
----
package com.example.fraud;
-import com.example.fraud.FraudDetectionController;
-import com.jayway.restassured.module.mockmvc.RestAssuredMockMvc;
-
import org.junit.Before;
+import com.jayway.restassured.module.mockmvc.RestAssuredMockMvc;
+
public class FraudBase {
@Before
public void setup() {
- RestAssuredMockMvc.standaloneSetup(new FraudDetectionController());
+ RestAssuredMockMvc.standaloneSetup(new FraudDetectionController(),
+ new FraudStatsController(stubbedStatsProvider()));
+ }
+
+ private StatsProvider stubbedStatsProvider() {
+ return fraudType -> {
+ switch (fraudType) {
+ case DRUNKS:
+ return 100;
+ case ALL:
+ return 200;
+ }
+ return 0;
+ };
}
public void assertThatRejectionReasonIsNull(Object rejectionReason) {
@@ -1312,7 +1321,7 @@ Example of a `pom.xml` inside the `server` folder.
UTF-8
1.8
1.1.0.BUILD-SNAPSHOT
- Camden.BUILD-SNAPSHOT
+ Dalston.BUILD-SNAPSHOT
diff --git a/samples/standalone/contracts/com/example/server/client1/expectation.groovy b/samples/standalone/contracts/com/example/server/client1/expectation.groovy
index 47b9ba6662..e798cdc7eb 100644
--- a/samples/standalone/contracts/com/example/server/client1/expectation.groovy
+++ b/samples/standalone/contracts/com/example/server/client1/expectation.groovy
@@ -3,13 +3,13 @@ package contracts
org.springframework.cloud.contract.spec.Contract.make {
request { // (1)
method 'PUT' // (2)
- url '/fraudcheck1' // (3)
+ url '/fraudcheck' // (3)
body([ // (4)
- clientId: value(consumer(regex('[0-9]{10}'))),
+ clientId: $(regex('[0-9]{10}')),
loanAmount: 99999
])
headers { // (5)
- header('Content-Type', 'application/vnd.fraud.v1+json')
+ contentType('application/vnd.fraud.v1+json')
}
}
response { // (6)
@@ -19,21 +19,20 @@ org.springframework.cloud.contract.spec.Contract.make {
rejectionReason: "Amount too high"
])
headers { // (9)
- header('Content-Type': value(
- producer(regex('application/vnd.fraud.v1.json.*')),
- consumer('application/vnd.fraud.v1+json'))
- )
+ contentType('application/vnd.fraud.v1+json')
}
}
}
/*
Since we don't want to force on the user to hardcode values of fields that are dynamic
-(timestamps, database ids etc.), one can provide parametrize those entries by using the
-`value(consumer(...), producer(...))` method. That way what's present in the `consumer`
-section will end up in the produced stub. What's there in the `producer` will end up in the
-autogenerated test. If you provide only the regular expression side without the concrete
-value then Spring Cloud Contract will generate one for you.
+(timestamps, database ids etc.), one can parametrize those entries. If you wrap your field's
+ value in a `$(...)` or `value(...)` and provide a dynamic value of a field then
+ the concrete value will be generated for you. If you want to be really explicit about
+ which side gets which value you can do that by using the `value(consumer(...), producer(...))` notation.
+ That way what's present in the `consumer` section will end up in the produced stub. What's
+ there in the `producer` will end up in the autogenerated test. If you provide only the
+ regular expression side without the concrete value then Spring Cloud Contract will generate one for you.
From the Consumer perspective, when shooting a request in the integration test:
diff --git a/samples/standalone/dsl/http-server/src/test/resources/contracts/fraud/shouldMarkClientAsFraud.groovy b/samples/standalone/dsl/http-server/src/test/resources/contracts/fraud/shouldMarkClientAsFraud.groovy
index 1745c3dffa..e798cdc7eb 100644
--- a/samples/standalone/dsl/http-server/src/test/resources/contracts/fraud/shouldMarkClientAsFraud.groovy
+++ b/samples/standalone/dsl/http-server/src/test/resources/contracts/fraud/shouldMarkClientAsFraud.groovy
@@ -1,39 +1,38 @@
package contracts
org.springframework.cloud.contract.spec.Contract.make {
- request { // (1)
- method 'PUT' // (2)
- url '/fraudcheck' // (3)
- body([ // (4)
- clientId: value(consumer(regex('[0-9]{10}'))),
- loanAmount: 99999
- ])
- headers { // (5)
- header('Content-Type', 'application/vnd.fraud.v1+json')
- }
- }
- response { // (6)
- status 200 // (7)
- body([ // (8)
- fraudCheckStatus: "FRAUD",
- rejectionReason: "Amount too high"
- ])
- headers { // (9)
- header('Content-Type': value(
- producer(regex('application/vnd.fraud.v1.json.*')),
- consumer('application/vnd.fraud.v1+json'))
- )
- }
- }
+ request { // (1)
+ method 'PUT' // (2)
+ url '/fraudcheck' // (3)
+ body([ // (4)
+ clientId: $(regex('[0-9]{10}')),
+ loanAmount: 99999
+ ])
+ headers { // (5)
+ contentType('application/vnd.fraud.v1+json')
+ }
+ }
+ response { // (6)
+ status 200 // (7)
+ body([ // (8)
+ fraudCheckStatus: "FRAUD",
+ rejectionReason: "Amount too high"
+ ])
+ headers { // (9)
+ contentType('application/vnd.fraud.v1+json')
+ }
+ }
}
/*
Since we don't want to force on the user to hardcode values of fields that are dynamic
-(timestamps, database ids etc.), one can provide parametrize those entries by using the
-`value(consumer(...), producer(...))` method. That way what's present in the `consumer`
-section will end up in the produced stub. What's there in the `producer` will end up in the
-autogenerated test. If you provide only the regular expression side without the concrete
-value then Spring Cloud Contract will generate one for you.
+(timestamps, database ids etc.), one can parametrize those entries. If you wrap your field's
+ value in a `$(...)` or `value(...)` and provide a dynamic value of a field then
+ the concrete value will be generated for you. If you want to be really explicit about
+ which side gets which value you can do that by using the `value(consumer(...), producer(...))` notation.
+ That way what's present in the `consumer` section will end up in the produced stub. What's
+ there in the `producer` will end up in the autogenerated test. If you provide only the
+ regular expression side without the concrete value then Spring Cloud Contract will generate one for you.
From the Consumer perspective, when shooting a request in the integration test:
diff --git a/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Request.groovy b/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Request.groovy
index 372728945e..b43f940111 100644
--- a/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Request.groovy
+++ b/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Request.groovy
@@ -196,6 +196,14 @@ class Request extends Common {
return value(client)
}
+ DslProperty value(Pattern client) {
+ return value(new ClientDslProperty(client))
+ }
+
+ DslProperty $(Pattern client) {
+ return value(client)
+ }
+
@Override
DslProperty value(ClientDslProperty client, ServerDslProperty server) {
if (server.clientValue instanceof Pattern) {
diff --git a/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Response.groovy b/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Response.groovy
index 8e9acdd792..d758605642 100644
--- a/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Response.groovy
+++ b/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Response.groovy
@@ -103,6 +103,14 @@ class Response extends Common {
return value(server)
}
+ DslProperty value(Pattern server) {
+ return value(new ServerDslProperty(server))
+ }
+
+ DslProperty $(Pattern server) {
+ return value(server)
+ }
+
@Override
DslProperty value(ClientDslProperty client, ServerDslProperty server) {
if (client.clientValue instanceof Pattern) {
diff --git a/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcMethodBodyBuilderSpec.groovy b/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcMethodBodyBuilderSpec.groovy
index 430d6986c7..74712d1b2a 100644
--- a/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcMethodBodyBuilderSpec.groovy
+++ b/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcMethodBodyBuilderSpec.groovy
@@ -1697,6 +1697,7 @@ World.'''"""
}
@Issue('#149')
+ @Unroll
def "should allow easier way of providing dynamic values"() {
given:
Contract contractDsl = Contract.make {
@@ -1704,6 +1705,7 @@ World.'''"""
method 'GET'
urlPath '/get'
body([
+ duck: $(regex("[0-9]")),
alpha: $(anyAlphaUnicode()),
number: $(anyNumber()),
aBoolean: $(aBoolean()),
@@ -1734,7 +1736,7 @@ World.'''"""
}
}
}
- MethodBodyBuilder builder = new MockMvcSpockMethodRequestProcessingBodyBuilder(contractDsl, properties)
+ MethodBodyBuilder builder = methodBuilder(contractDsl)
BlockBuilder blockBuilder = new BlockBuilder(" ")
when:
builder.appendTo(blockBuilder)
@@ -1749,6 +1751,10 @@ World.'''"""
test.contains('assertThatJson(parsedJson).field("ip").matches("([01]?\\\\d\\\\d?|2[0-4]\\\\d|25[0-5])\\\\.([01]?\\\\d\\\\d?|2[0-4]\\\\d|25[0-5])\\\\.([01]?\\\\d\\\\d?|2[0-4]\\\\d|25[0-5])\\\\.([01]?\\\\d\\\\d?|2[0-4]\\\\d|25[0-5])")')
test.contains('assertThatJson(parsedJson).field("uuid").matches("[a-z0-9]{8}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{12}")')
!test.contains('cursor')
+ where:
+ methodBuilder << [{ Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties)},
+ { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties)}]
+
}
@Issue('#162')