使用 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)
?
-> 表示过滤表达式,需要括号将表达式包裹起来
@
-> 当前选择的元素(因为我们没有从根向下钻取,它引用根)
我正在尝试 validate/match 请求 body 针对 JSON 使用 Wiremock 的架构。据我所知,Wiremock 不首先 class 支持模式验证,但仅支持 JSONPath.
不幸的是,我无法理解与有效请求主体匹配的正确 JSON-Path 表达式。
假设,我有一个端点,您可以在其中 POST/PATCH 书名。应匹配以下请求 body:
{
"title": "Harry Potter and the Philosopher's Stone"
}
使用查找 title
属性.
但是,具有附加属性的请求主体应该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)?
-> 表示过滤表达式,需要括号将表达式包裹起来@
-> 当前选择的元素(因为我们没有从根向下钻取,它引用根)