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 f539dada40..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,36 +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) - 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") - } - } + 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 542083d0b1..7578f1f656 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 cb9941f427..a459219b04 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 665dc38d7c..7677e08e16 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')