为什么 WireMock 无法按请求 Header 正确匹配?
结论
Header 匹配语法没有明显问题。根据日志,WireMock 实际命中的并不是展示出来的两条配置:
{
"status": 201,
"bodyFileName": "status.json"
}
第一条配置使用的响应文件却是 payment-consents.json。这意味着当前实例中还有一条匹配相同 method + url 的 stub,或者修改后的 routes.json 没有被当前容器正确加载。
最可能的原因
1. 存在未限定 Header 的旧路由
WireMock 中可能还保留着类似的配置:
{
"request": {
"method": "POST",
"url": "/middleware-nz-sandbox/v2.0/domestic-payment-consents"
},
"response": {
"status": 201,
"bodyFileName": "status.json"
}
}
这条规则不检查 x-fapi-interaction-id,所以任何发往该 URL 的 POST 请求都可能命中它。
如果多个 stub 同时满足请求,又没有明确设置 priority,WireMock 的最终选择还会受到加载顺序等因素影响。因此,不要依赖 JSON 文件中的排列顺序来处理规则冲突。
2. routes.json 没有作为 WireMock mapping 文件加载
Standalone WireMock 通常从文件根目录下的 mappings 目录加载 stub,并从 __files 目录读取响应文件。建议采用下面的目录结构:
wiremock/
├── mappings/
│ ├── payment-consents-okay.json
│ └── payment-consents-error.json
└── __files/
├── payment-consents.json
└── payment-consents-error.json
如果 Docker volume 挂载到了错误的目录,容器使用了不同的文件根目录,或者 routes.json 的顶层结构不符合当前加载方式,WireMock 可能仍在使用镜像内、旧 volume 中或其他目录里的 mapping。
另外,宿主机文件发生变化后,WireMock 通常不会自动重新加载所有文件 mapping。修改配置后,应重启容器,或者通过 Admin API 重新导入或 reset mappings。
建议配置
把两条规则拆成独立的 mapping 文件,并明确设置优先级。
mappings/payment-consents-okay.json:
{
"priority": 1,
"request": {
"method": "POST",
"urlPath": "/middleware-nz-sandbox/v2.0/domestic-payment-consents",
"headers": {
"x-fapi-interaction-id": {
"equalTo": "okay"
}
}
},
"response": {
"status": 201,
"bodyFileName": "payment-consents.json"
}
}
mappings/payment-consents-error.json:
{
"priority": 1,
"request": {
"method": "POST",
"urlPath": "/middleware-nz-sandbox/v2.0/domestic-payment-consents",
"headers": {
"x-fapi-interaction-id": {
"equalTo": "error"
}
}
},
"response": {
"status": 500,
"bodyFileName": "payment-consents-error.json"
}
}
如果确实需要一条不检查 Header 的兜底规则,应给它设置更低的优先级。WireMock 的 priority 数字越小,优先级越高:
{
"priority": 10,
"request": {
"method": "POST",
"urlPath": "/middleware-nz-sandbox/v2.0/domestic-payment-consents"
},
"response": {
"status": 400,
"jsonBody": {
"error": "Unsupported x-fapi-interaction-id"
},
"headers": {
"Content-Type": "application/json"
}
}
}
如何确认 WireMock 实际加载了什么
先查询运行中实例的 mappings:
curl http://localhost:7070/__admin/mappings
然后在返回结果中搜索:
/middleware-nz-sandbox/v2.0/domestic-payment-consents
重点检查:
- 是否存在返回
status.json的旧 stub; - 两条 Header 规则是否已经加载;
- 是否存在多份重复的 mapping;
- 实际配置的
priority是多少。
还可以查询未匹配或接近匹配的请求:
curl http://localhost:7070/__admin/requests/unmatched
如果可以在容器内执行只读检查,还应确认 mapping 文件确实挂载到了 WireMock 使用的文件根目录,而不是只存在于宿主机的另一个路径中。
Header 匹配本身的注意事项
Header 名称的大小写通常不会造成问题,因为 HTTP Header 名称不区分大小写。不过,equalTo 会对 Header 值进行精确匹配,所以下面的值并不等价:
error
Error
error
如果需要忽略值的大小写,并且当前版本支持相应参数,可以使用:
"headers": {
"x-fapi-interaction-id": {
"equalTo": "error",
"caseInsensitive": true
}
}
不过,当前日志已经明确显示值为 [error],所以问题更可能出在 mapping 没有正确加载,或者存在重复的 stub,而不是 Header 值本身。
最直接的线索是 bodyFileName: "status.json"。先找到这条旧规则,将其删除、禁用或调低优先级,再确认两条 Header mapping 已经出现在 GET /__admin/mappings 的返回结果中。
备注:内容仅供参考。
