空手道 - 有条件地验证 Json 模式
Karate - Conditionally validating Json schema
我正在尝试为以下响应编写 JSON 架构。响应是动态的,它可以是 person
详细信息或 organization
详细信息。如果响应中的 customerType
是 person
,则响应将包含人员对象(组织对象将不可用)。如果 customerType
是 org
,组织详细信息将包含在响应中(人员对象将不可用)。下面给出了两种不同的预期响应
{
"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"
}
我目前面临的问题是,如果响应中的 customerType
是 person
,它会抛出以下错误
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% 知道响应将是什么。请花点时间阅读以下内容:
我正在尝试为以下响应编写 JSON 架构。响应是动态的,它可以是 person
详细信息或 organization
详细信息。如果响应中的 customerType
是 person
,则响应将包含人员对象(组织对象将不可用)。如果 customerType
是 org
,组织详细信息将包含在响应中(人员对象将不可用)。下面给出了两种不同的预期响应
{
"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"
}
我目前面临的问题是,如果响应中的 customerType
是 person
,它会抛出以下错误
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% 知道响应将是什么。请花点时间阅读以下内容: