diff --git a/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Body.groovy b/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Body.groovy index 5ecd22f00e..1b7eecd32c 100644 --- a/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Body.groovy +++ b/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Body.groovy @@ -48,6 +48,10 @@ class Body extends DslProperty { this("${bodyAsValue}") } + Body(Number bodyAsValue) { + super(bodyAsValue) + } + Body(GString bodyAsValue) { super(bodyAsValue, bodyAsValue) } diff --git a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MethodBodyBuilder.groovy b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MethodBodyBuilder.groovy index 4de0a50232..0fb64a36c2 100644 --- a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MethodBodyBuilder.groovy +++ b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MethodBodyBuilder.groovy @@ -297,7 +297,7 @@ abstract class MethodBodyBuilder { private void addJsonResponseBodyCheck(BlockBuilder bb, convertedResponseBody, BodyMatchers bodyMatchers) { appendJsonPath(bb, getResponseAsString()) - Object copiedBody = convertedResponseBody.clone() + Object copiedBody = cloneBody(convertedResponseBody) convertedResponseBody = JsonToJsonPathsConverter.removeMatchingJsonPaths(convertedResponseBody, bodyMatchers) JsonPaths jsonPaths = new JsonToJsonPathsConverter(configProperties).transformToJsonPathWithTestsSideValues(convertedResponseBody) jsonPaths.each { @@ -369,6 +369,14 @@ abstract class MethodBodyBuilder { bb.addLine(postProcessJsonPathCall(method)) } + private Object cloneBody(Object object) { + try { + return object.clone() + } catch (CloneNotSupportedException e) { + return object + } + } + protected Object value(def body, BodyMatcher bodyMatcher) { if (bodyMatcher.matchingType() == MatchingType.EQUALITY || !bodyMatcher.value()) { return retrieveObjectByPath(body, bodyMatcher.path()) diff --git a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/util/ContentUtils.groovy b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/util/ContentUtils.groovy index c804e6e1ce..553dac2913 100644 --- a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/util/ContentUtils.groovy +++ b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/util/ContentUtils.groovy @@ -332,6 +332,10 @@ class ContentUtils { } } + static ContentType recognizeContentTypeFromContent(Number number) { + return ContentType.TEXT + } + static ContentType recognizeContentTypeFromContent(Object gstring) { return ContentType.UNKNOWN } diff --git a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/util/JsonToJsonPathsConverter.groovy b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/util/JsonToJsonPathsConverter.groovy index db061dc804..915e404201 100644 --- a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/util/JsonToJsonPathsConverter.groovy +++ b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/util/JsonToJsonPathsConverter.groovy @@ -74,7 +74,7 @@ class JsonToJsonPathsConverter { * @return json with removed entries */ static def removeMatchingJsonPaths(def json, BodyMatchers bodyMatchers) { - def jsonCopy = json.clone() + def jsonCopy = cloneBody(json) DocumentContext context = JsonPath.parse(jsonCopy) if (bodyMatchers?.hasMatchers()) { bodyMatchers.jsonPathMatchers().each { BodyMatcher matcher -> @@ -90,6 +90,14 @@ class JsonToJsonPathsConverter { return jsonCopy } + private static Object cloneBody(Object object) { + try { + return object.clone() + } catch (CloneNotSupportedException e) { + return object + } + } + /** * For the given matcher converts it into a JSON path * that checks the regex pattern or equality 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 b307028149..3af4f13f7a 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 @@ -2158,4 +2158,36 @@ World.'''""" "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } "JaxRsClientJUnitMethodBodyBuilder" | { Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } } + + @Issue("#226") + def "should work properly when body is an integer [#methodBuilderName]"() { + given: + Contract contractDsl = Contract.make { + request { + method 'GET' + url '/api/v1/xxxx' + body(12000) + } + response { + status 200 + body(12000) + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + and: + builder.appendTo(blockBuilder) + String test = blockBuilder.toString() + when: + SyntaxChecker.tryToCompile(methodBuilderName, test) + then: + requestAssertion(test) + responseAssertion(test) + where: + methodBuilderName | methodBuilder | requestAssertion | responseAssertion + "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | { String body -> body.contains("body('''12000''')") } | { String body -> body.contains('responseBody == "12000"') } + "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | { String body -> body.contains('body("12000")') } | { String body -> body.contains('assertThat(responseBody).isEqualTo("12000");') } + "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | { String body -> body.contains(""".method('GET', entity('12000', 'text/plain'))""") } | { String body -> body.contains('responseBody == "12000"') } + "JaxRsClientJUnitMethodBodyBuilder" | { Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } | { String body -> body.contains(""".method("GET", entity("12000", "text/plain"))""") } | { String body -> body.contains('assertThat(responseBody).isEqualTo("12000")') } + } }