使用 Wiremock 验证 Json Body

Validate Json Body with Wiremock

我正在尝试 validate/match 请求 body 针对 JSON 使用 Wiremock 的架构。据我所知,Wiremock 不首先 class 支持模式验证,但仅支持 JSONPath.

不幸的是,我无法理解与有效请求主体匹配的正确 JSON-Path 表达式。

假设,我有一个端点,您可以在其中 POST/PATCH 书名。应匹配以下请求 body:

{
   "title": "Harry Potter and the Philosopher's Stone"
}

使用查找 title 属性.

的 JsonPath 表达式很容易

但是,具有附加属性的请求主体应该NOT有效。我事先不知道客户将发送哪些或多少额外​​的属性,但以下文件应该 - 例如 - 不匹配:

{
   "title": "Harry Potter and the Philosopher's Stone",
   "isbn": "0-7475-3269-9"
}
{
   "title": "Harry Potter and the Philosopher's Stone",
   "isbn": "0-7475-3269-9",
   "author": "J. K. Rowling"
}
{
   "title": "Harry Potter and the Philosopher's Stone",
   "xyz": "bla-bla-bla"
}

JSON 路径表达式应该是什么样子,以便只匹配只有标题而没有其他任何内容的请求正文?

或者除了(滥用)JSONWiremock 中的路径来实现我的目标之外,还有其他方法吗?

WireMock 在后台使用 Goessner's JSON-Path 实现,如果这有任何意义的话

根据您想要实现的目标,有几种选择。

如果您只需要匹配 title == "Harry Potter and the Philosopher's Stone" 的情况,并且这是 JSON 中的唯一字段,您可以简单地执行:

"bodyPatterns": [{
    "equalToJson": "{ \"title\": \"Harry Potter and the Philosopher's Stone\" }",
    "ignoreExtraElements": false
}]

equalToJson属性根据要求匹配body等同于你的匹配器。通过将 ignoreExtraElements 属性 添加为 false,它将确保您拥有绝对匹配。我相信 ignoreExtraElements 默认为 true,因此您必须明确将其设置为 false。

如果您需要在任何有标题值的情况下进行匹配,您需要像这样的东西:

"bodyPatterns": [{
    "matchesJsonPath": "$.title"
}, {
    "matchesJsonPath": "$[?(@.size() == 1)]"
}]

在此示例中,我们正在检查 body 是否具有 某些 字段的 title 值,然后还检查整个 body(在 JsonPath 中引用为 $)的大小为 1。第二个 matchesJsonPath 符号的作用细分:

  • $ -> root object(在本例中,整个请求 body)
  • ? -> 表示过滤表达式,需要括号将表达式包裹起来
  • @ -> 当前选择的元素(因为我们没有从根向下钻取,它引用根)