我正在尝试使用 Wiremock 验证/匹配请求正文与 JSON 模式。据我所知,Wiremock 没有对模式验证的一流支持,但仅支持 JSONPath。
不幸的是,我无法全神贯注于匹配有效请求主体的正确 JSON-Path 表达式。
假设,我有一个端点,您可以在其中发布/修补书名。应匹配以下请求正文:
{
"title": "Harry Potter and the Philosopher's Stone"
}
使用查找 title
属性的 JsonPath 表达式很容易。
但是,具有附加属性的请求体应该NOT 有效。我事先不知道客户将发送哪些或多少额外的属性(property),但以下文件应该 - 例如 - 不匹配:
{
"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 路径表达式应该是什么样子,以便只匹配只有标题而没有其他任何内容的请求正文?
或者除了(滥用)Wiremock 中的 JSONPath 之外,还有其他方法可以实现我的目标吗?
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
属性匹配基于请求正文等同于您的匹配器。通过将 ignoreExtraElements
属性添加为 false,它将确保您拥有绝对匹配。我相信 ignoreExtraElements
默认为 true,因此您必须明确将其设置为 false。
如果您需要在任何有标题值的情况下进行匹配,您需要这样的东西:
"bodyPatterns": [{
"matchesJsonPath": "$.title"
}, {
"matchesJsonPath": "$[?(@.size() == 1)]"
}]
在此示例中,我们检查正文是否具有 title
字段的 some 值,然后还检查整个正文(在 JsonPath 中引用为 $
) 的大小为 1。分解第二个 matchesJsonPath
符号的作用:
$
-> 根对象(在本例中为整个请求主体)?
-> 表示过滤表达式,需要括号将表达式包裹起来@
-> 当前选择的元素(因为我们没有从根向下钻取,它引用根)
关于java - 使用 Wiremock 验证 Json 主体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66386750/