Внедрить matchJsonPath из Groovy в Spring Cloud Contract

При написании контракта Spring Cloud в Groovy я хочу указать явное выражение пути 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  } ]
}

Возможно ли это с помощью потребителей, bodyMatcher или других средств Groovy DSL?


person Jens Jensen    schedule 31.01.2020    source источник


Ответы (1)


Есть некоторые возможности сопоставления по пути 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
  }
}

Я сослался на несколько строк

1: «byEquality ()» в разделе bodyMatchers означает: ввод от потребителя должен быть равен значению, предоставленному в теле для соответствия этому контракту / заглушке, другими словами, должен быть «id».

2: Я не уверен, насколько хорошо решение // 1 будет работать, когда свойство находится в списке, и вы хотите, чтобы заглушка была гибкой в ​​зависимости от количества предоставленных элементов. Поэтому я также включил это byRegex, что в основном означает, что для любого элемента в списке свойство foo должно иметь точное значение «foo». Однако я действительно не знаю, зачем вам это нужно.

3: Вот где на самом деле bodyMatcher наиболее полезны. Эта строка означает: соответствие этому контракту, если каждая панель свойств в списке элементов не является пустой строкой. Это позволяет иметь динамическую заглушку с гибким размером списков / массивов.

Чтобы заглушка соответствовала, должны быть выполнены все условия в bodyMatchers.

person I.Brok    schedule 03.03.2020
comment
Селектор items[*] выбирает разные элементы в каждом предложении bodyMatchers. Мне нужно, чтобы это был такой же пункт. Добавил пример для пояснения. - person Jens Jensen; 23.03.2020