空手道 - 有条件地验证 Json 模式

Karate - Conditionally validating Json schema

我正在尝试为以下响应编写 JSON 架构。响应是动态的,它可以是 person 详细信息或 organization 详细信息。如果响应中的 customerTypeperson,则响应将包含人员对象(组织对象将不可用)。如果 customerTypeorg,组织详细信息将包含在响应中(人员对象将不可用)。下面给出了两种不同的预期响应

{
    "customerType" : "person",
    "person" : {
        "fistName" : "A",
        "lastName" : "B"
    },
    "id" : 1,
    "requestDate" : "2021-11-11"
}

{
    "customerType" : "org",
    "organization" : {
        "orgName" : "A",
        "orgAddress" : "B"
    },
    "id" : 2,
    "requestDate" : "2021-11-11"
}

我正在尝试使用下面给出的架构来验证上述条件

{
    "customerType" : "#string",
    "organization" : "#? karate.match(response.customerType, 'org').pass ? karate.match(_, organizationSchema).pass : true)",
    "person" : "#? karate.match(response.customerType, 'person').pass ? karate.match(_, personSchema).pass : true"),
    "id" : "#number",
    "requestDate" : "#string"
}

我目前面临的问题是,如果响应中的 customerTypeperson,它会抛出以下错误

all key-values did not match, expected has un-matched keys: [organization]

有什么方法可以在模式中指定如果个人对象可用,组织对象将不可用,反之亦然

如果您坚持在一个“单一”架构中执行此操作,那么空手道不适合您。否则,请继续阅读。

空手道鼓励重复使用模式“块”。这里有两种可能的解决方案来满足您的要求。我希望你多读一些关于如何在空手道脚本中嵌入 JS,并在进行匹配之前操纵 JSON 的内容,如果你真的这样做,甚至可以使用 karate.merge() 来“合并”JSON变得花哨。您不需要总是进行“精确”匹配,有时 contains 可以很好地完成工作。

* def personSchema = { firstName: '#string', lastName: '#string' }
* def orgSchema = { orgName: '#string', orgAddress: '#string' }
* def schema = { customerType: '#string', id: '#number' }

* def response1 = { customerType: 'person', person: { firstName: 'Foo', lastName: 'Bar' }, id: 1 }
* match response1 contains schema
* def extra = response1.person ? { person: '#(personSchema)' } : { organization: '#(orgSchema)' }
* match response1 contains extra

* def response2 = { customerType: 'org', organization: { orgName: 'Foo', orgAddress: 'Bar' }, id: 2 }
* if (response2.person) schema.person = personSchema; else schema.organization = orgSchema
* match response2 == schema

综上所述,我强烈不鼓励像这样的“聪明”测试,它只会导致可维护性问题。请尽可能坚持普通场景并设置您的测试/请求,以便您 100% 知道响应将是什么。请花点时间阅读以下内容: