将来自Groovy的matchesJsonPath注入Spring云契约

将来自Groovy的matchesJsonPath注入Spring云契约,groovy,spring-cloud-contract,Groovy,Spring Cloud Contract,在Groovy中编写Spring云契约时, 我想指定一个显式JSON路径表达式。 表达方式: "$.['variants'][*][?(@.['name'] == 'product_0004' && @.['selected'] == true)]" 应出现在生成的json中,如下所示: { "request" : { "bodyPatterns": [ { "matchesJsonPath": "$.['variants'][*][?(@.['name

在Groovy中编写Spring云契约时, 我想指定一个显式JSON路径表达式。 表达方式:

"$.['variants'][*][?(@.['name'] == 'product_0004' && @.['selected'] == true)]"
应出现在生成的json中,如下所示:

{
  "request" : {
    "bodyPatterns": [ {
      "matchesJsonPath": "$.['variants'][*][?(@.['name'] == 'product_0004' && @.['selected'] == true)]"
    } ]
  }
}
为了匹配,例如:

{ "variants": [
    { "name": "product_0003", "selected": false },
    { "name": "product_0004", "selected": true  },
    { "name": "product_0005", "selected": false } ]
}
{ "variants": [
    { "name": "product_0003", "selected": false },
    { "name": "product_0004", "selected": false },
    { "name": "product_0005", "selected": true  } ]
}
和不匹配,例如:

{ "variants": [
    { "name": "product_0003", "selected": false },
    { "name": "product_0004", "selected": true  },
    { "name": "product_0005", "selected": false } ]
}
{ "variants": [
    { "name": "product_0003", "selected": false },
    { "name": "product_0004", "selected": false },
    { "name": "product_0005", "selected": true  } ]
}

使用Groovy DSL的使用者、BodyMatcher或其他一些功能是否可能实现这一点?

在json路径上进行匹配有一些可能性,但您不一定要使用它来匹配显式值,而是使用正则表达式为使用者创建灵活的存根。不过也有一些可能性

因此,body部分是带有硬编码值的静态请求主体,而bodyMatchers部分提供了使来自使用者端的存根匹配更加灵活的能力

Contract.make {
  request {
    method 'POST'
    url '/some-url'
    body ([
      id: id
      items: [
         foo: foo
         bar: bar
      ],
      [
         foo: foo
         bar: foo
      ]
    ])
    bodyMatchers {
        jsonPath('$.id', byEquality())       //1
        jsonPath('$.items[*].foo', byRegex('(?:^|\\W)foo(?:$|\\W)'))    //2
        jsonPath('$.items[*].bar', byRegex(nonBlank()))     //3
      }
      headers {
          contentType(applicationJson())
      }
  }
  response {
    status 200
  }
}
我引用了一些行

bodyMatchers部分中的“byEquality()”表示:消费者的输入必须等于正文中提供的值,以匹配此合同/存根,换句话说,必须是“id”

2:我不确定//1解决方案在属性位于列表中时会有多好的效果,您希望存根能够灵活地处理提供的项目数量。因此,我还包括了这个byRegex,这基本上意味着,对于列表中的任何项目,属性foo必须具有精确的值“foo”。然而,我真的不知道你为什么要这么做

3:这就是bodyMatchers实际上最有用的地方。此行的意思是:如果项目列表中的每个属性栏都是非空字符串,则匹配此合同。这允许您拥有一个具有灵活列表/数组大小的动态存根


bodyMatchers中的所有条件都需要满足,存根才能匹配。

选择符在每个bodyMatchers子句中选择不同的项。我需要它是相同的条款。增加了一个澄清的例子。