Karate中字段与子数组顺序打乱的两个JSON对象如何实现匹配校验
问题原因
你之前的校验失败存在两个核心问题:
- Karate默认数组匹配是严格校验元素顺序的
- 你使用
users[*].fdpAccounts提取到的是所有user的fdpAccounts组成的集合(结构为[ [account1, account2], null ]),直接对这个集合用contains only无法满足每个子数组内部的顺序忽略需求。
解决方案
方案1:开启全局忽略数组顺序(最简便)
只需要在场景开头(或Feature的Background块中)添加匹配配置,开启全局数组顺序忽略即可。contains匹配本身会自动忽略实际返回中不在预期结构里的额外字段,完美符合你的需求。
修改后的代码如下:
Scenario: Company multiple fdpAccounts call # 开启数组匹配忽略顺序,仅当前场景生效,写在Background则整个Feature生效 * configure match = { ignoreOrder: true } * def query = read('query/multiple-fdpAccounts.graphql') * def expectedResult = read('result/multiple-fdpAccounts.json') Given url downstreamApiUrlBase And request { query: '#(query)' } When method post Then status 200 # 直接匹配整个预期结构,自动忽略额外字段、忽略所有嵌套数组顺序 Then match response contains expectedResult Then match response.errors == '#notpresent'
方案2:针对单个嵌套数组手动校验
如果不希望全局开启忽略顺序影响其他用例的默认校验规则,可以单独对需要忽略顺序的fdpAccounts子数组做校验:
Scenario: Company multiple fdpAccounts call * def query = read('query/multiple-fdpAccounts.graphql') * def expectedResult = read('result/multiple-fdpAccounts.json') * def expectedUsers = expectedResult.data.company.users Given url downstreamApiUrlBase And request { query: '#(query)' } When method post Then status 200 # 先校验公司ID符合预期 Then match response.data.company.id == expectedResult.data.company.id # 校验user列表的ID完全匹配,忽略顺序(如果user顺序也可能乱可以加这行,否则可省略) Then match response.data.company.users[*].id contains only expectedUsers[*].id # 逐个校验每个user的fdpAccounts,子数组忽略顺序 * match each response.data.company.users == function(user, index) { var expectedUser = expectedUsers[index]; match user.id == expectedUser.id; expectedUser.fdpAccounts != null ? match user.fdpAccounts contains only expectedUser.fdpAccounts : match user.fdpAccounts == null; return true; } Then match response.errors == '#notpresent'
适用场景说明
- 如果你团队的接口普遍不需要校验数组顺序,优先选方案1,代码最简洁
- 如果你只有个别用例需要忽略数组顺序,选方案2,不影响全局默认校验逻辑
内容的提问来源于stack exchange,提问作者user3439221
相关产品推荐
相关产品推荐

