Pact 当主体为列表时,Spring云契约生成主体为空的契约
我正试图从SpringCloud合同中生成契约,如下图所示。它只在响应体根是json时工作,但是当我试图生成返回json数组的pact时,它会生成一个空体。我尝试过使用字符串格式为“[{}…]”的groovy dsl和使用DslPropertyPact 当主体为列表时,Spring云契约生成主体为空的契约,pact,spring-cloud-contract,Pact,Spring Cloud Contract,我正试图从SpringCloud合同中生成契约,如下图所示。它只在响应体根是json时工作,但是当我试图生成返回json数组的pact时,它会生成一个空体。我尝试过使用字符串格式为“[{}…]”的groovy dsl和使用DslProperty[value()…]。这是我的合同: 使用字符串格式 Contract.make { description "should return a list of dummy object with dummy value. Generates pact wi
[value()…]
。这是我的合同:
使用字符串格式
Contract.make {
description "should return a list of dummy object with dummy value. Generates pact with empty json"
request {
method GET()
url("/dummy")
}
response {
body("""[{"value": "Hi! I'm a dummy object ;)"}]""")
headers {
contentType applicationJson()
}
status 200
}}
具有特殊属性
Contract.make {
description "should return a list of dummy object with dummy value. Generates pact with empty body list"
request {
method GET()
url("/dummy")
}
response {
body([value(value: "Hi! I'm a dummy object ;)")])
headers {
contentType applicationJson()
}
status 200
}}
这就是在target/pacts生成的文件
{
"provider": {
"name": "Provider"
},
"consumer": {
"name": "Consumer"
},
"interactions": [
{
"description": "should return a list of dummy object with dummy value. Generates pact with empty body list",
"request": {
"method": "GET",
"path": "/dummy"
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json"
},
"body": [
],
"matchingRules": {
"header": {
"Content-Type": {
"matchers": [
{
"match": "regex",
"regex": "application/json.*"
}
],
"combine": "AND"
}
}
}
}
},
{
"description": "should return a list of dummy object with dummy value. Generates pact with empty json",
"request": {
"method": "GET",
"path": "/dummy"
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json"
},
"body": {
},
"matchingRules": {
"header": {
"Content-Type": {
"matchers": [
{
"match": "regex",
"regex": "application/json.*"
}
],
"combine": "AND"
}
}
}
}
}
],
"metadata": {
"pactSpecification": {
"version": "3.0.0"
},
"pact-jvm": {
"version": "3.5.23"
}
}}
我正在使用以下版本
<spring-cloud.version>Hoxton.BUILD-SNAPSHOT</spring-cloud.version>
<spring-cloud-contract.version>2.0.1.RELEASE</spring-cloud-contract.version>
<pact-jvm-provider-maven.version>3.5.23</pact-jvm-provider-maven.version>
另一方面,当使用DslProperty
查看插件代码时,我有一个类似[DslProperty{clientValue=DslProperty}]
的对象。第一个DslProperty正在被提取,但由于内容是另一个DslProperty,并且没有递归提取,我最终得到一个空的正文,因为v
不是Gstring
,String
,Number
,Map
,Collection
的实例。所以我又得到了一个空的身体
org.springframework.cloud.contract.verifier.spec.pact.BodyConverter
private static DslPart traverse(Object value, DslPart parent, Closure dslPropertyValueExtractor) {
...
if (v instanceof String) {
v = v.trim()
if (v.startsWith("{") && v.endsWith("}")) {
try {
v = jsonSlurper.parseText(v as String)
}
catch (JsonException ex) { /*it wasn't a JSON string after all...*/
}
}
}
...
private static void processCollection(Collection values, PactDslJsonArray jsonArray, Closure dslPropertyValueExtractor) {
values.forEach({
Object v = it
if (v instanceof DslProperty) {
v = dslPropertyValueExtractor(v)
}
if (v instanceof GString) {
v = ContentUtils.extractValue(v, dslPropertyValueExtractor)
}
if (v == null) {
jsonArray.nullValue()
}
else if (v instanceof String) {
jsonArray.string(v)
}
else if (v instanceof Number) {
jsonArray.number(v)
}
else if (v instanceof Map) {
PactDslJsonBody current = jsonArray.object()
traverse(v, current, dslPropertyValueExtractor)
current.closeObject()
}
else if (v instanceof Collection) {
PactDslJsonArray current = jsonArray.array()
traverse(v, current, dslPropertyValueExtractor)
current.closeArray()
}
})
}
我已经在上发布了一个示例,以防需要更多关于我如何构建项目的信息
在定义groovy契约文件时,我有没有做错什么?我想我对响应主体应该如何定义有些误解。您需要在主体中创建一个groovy对象数组,如下所示:
正文([
[值:“Object1”],
[值:“对象2”]
])
这样,spring cloud contracts将生成合同所需的正确代码。mm我明白了,所以我必须使用[]声明,而不是value()。这对我很有用,谢谢
private static void processCollection(Collection values, PactDslJsonArray jsonArray, Closure dslPropertyValueExtractor) {
values.forEach({
Object v = it
if (v instanceof DslProperty) {
v = dslPropertyValueExtractor(v)
}
if (v instanceof GString) {
v = ContentUtils.extractValue(v, dslPropertyValueExtractor)
}
if (v == null) {
jsonArray.nullValue()
}
else if (v instanceof String) {
jsonArray.string(v)
}
else if (v instanceof Number) {
jsonArray.number(v)
}
else if (v instanceof Map) {
PactDslJsonBody current = jsonArray.object()
traverse(v, current, dslPropertyValueExtractor)
current.closeObject()
}
else if (v instanceof Collection) {
PactDslJsonArray current = jsonArray.array()
traverse(v, current, dslPropertyValueExtractor)
current.closeArray()
}
})
}