As offered here: https://stackoverflow.com/questions/50580415/karate-array-field-become-object
by @ptrthomas
Maybe we need a karate.append() and karate.merge() (for merging 2 JSON objects). Feel free to raise a feature request.
I would love to see a merge function. I have data driven tests where not all assertions in the test data files are mandatory, and I'd like to merge a "default" json with them, allowing the values in the file to override these defaults.
@thunderstumpges done
Scenario: merge
* def foo = { a: 1 }
* def bar = karate.merge(foo, { b: 2 })
* match bar == { a: 1, b: 2 }
Scenario: append
* def foo = [{ a: 1 }]
* def bar = karate.append(foo, { b: 2 })
* match bar == [{ a: 1 }, { b: 2 }]
@thunderstumpges I hope you are aware of the contains keyword, because that's what most teams use when they don't care about all the fields. you can get even fancier with "fuzzy matching": https://github.com/intuit/karate#fuzzy-matching
Wow, thanks! That has GOT to be the fastest turnaround on a feature request ever! :)
Yes I have looked at contains and fuzzy matching. I actually do use fuzzy matching in a number of places.
I ran into friction with contains, as the parts being asserted in the response are nested in fairly complex ways, and I didn't want the test writers to have to replicate that nesting in their test data. I did also look into karate.map but with the "optional-ness" of the assertions, I didn't see how to "optionally map" into the response structure.
I do have a working solution in place, and I think the above will help even more with this, so Thanks!
But for those curious, below is an example of my scenario. Test writers fill in test data in yaml files which drive the tests:
Test Yaml:
- input: some text
response: '#regex ^response assertion$'
maybeMatchString: match if specified in test
maybeMatchArray:
- name: xxx
value: yyy
- input: another test
response: '#regex ^another response assertion$'
# note, no optional match data, so don't assert on it
And when matching to the response, the nesting is more complex:
```json
{
"innerResponse": {
"otherInnerObject" : {
"textToMatchResponse" : "response value"
}
},
"anotherMaybeObject" : {
"nested" : {
"maybeMatchString" : "match this if it was in the test"
},
"maybeMatchArray" : [
{
"name" : "match this if it was in the test",
"value" : "same"
}
]
}
@thunderstumpges okay, I probably don't yet understand the yaml part - but do blog about this or something, it sounds interesting. one more suggestion is that when dealing with complex nesting, JsonPath can be useful:
* def response =
"""
{
"innerResponse": {
"otherInnerObject": {
"textToMatchResponse": "response value"
}
},
"anotherMaybeObject": {
"nested": {
"maybeMatchString": "match this if it was in the test"
},
"maybeMatchArray": [
{
"name": "match this if it was in the test",
"value": "same"
}
]
}
}
"""
* def inner = $response..otherInnerObject
* match inner contains { textToMatchResponse: 'response value' }
Thanks, yes good idea!
released 0.9.3
Most helpful comment
@thunderstumpges done