1

I would like to check response from GET/birds request with a json schema. In my feature:

* def abs = read (birds.json)
* match response == abs.birdsSchema

I need to put the schema in a json file and not in the feature. I have to check additional values depending on gender. Ex: if gender is male then check if the color is blue and the tail is long or short. if gender is female then check if "sings" is true or false and number of eggs.

So I put in birds.json:

"birdsSchema":{
    "id": "#string",
    "owner": "#number",
    "town": "#? _ == 'New York' || _ == 'Washington'",
    "type": "object",
    "oneOf": [
        {
            "properties": {
                "gender": {"enum": ["male"]},
                "color":"blue",
                "tail": "#? _ == 'long' || _ == 'short'"
            }
        },
        {
            "properties": {
                "gender": {"enum": ["female"]},
                "sings" : "#? _ == true || _ == false"
                "eggs": "##number"
            }
        }
    ]
}

But it doesn't work. Error: com.intuit.karate.exception.KarateException: path: $[0].type, actual: 'female', expected: 'object', reason: not equal. How I can do this conditional check in my json file?

cygne
  • 527
  • 1
  • 10
  • 28

1 Answers1

2

Let's acknowledge that this is extra hard because if I understand your question correctly, the JSON keys you are looking for are dynamic.

Part of the fun of Karate is that there are at least 5 different ways I can think of to solve this elegantly. Here is just one:

* def response = { color: 'black', aaa: 'foo' }

* def schema = { color: '#? _ == "black" || _ == "white"' }
* def extra = (response.color == 'black' ? { aaa: '#string' } : { fff: '#string' })

* match response contains schema
* match response contains extra

If you create a JS function based on the hint above, you can probably get a better solution. Keep in mind that in a JS function you can use methods like karate.set to dynamically create keys. So there are many possibilities :)

edit: looks like the example above is wrong, and the keys are not dynamic. Then it is easy, keep in mind that $ refers to the JSON root:

* def response = { color: 'black', extra: 'foo' }    
* def schema = { color: '#? _ == "black" || _ == "white"', extra: '#($.color == "black" ? "foo" : "bar")' }    
* match response == schema
Peter Thomas
  • 54,465
  • 21
  • 84
  • 248
  • thanks for all your quick reply. I know how to do this in features thanks to Karate official tuto, but I wanted to do this in a json file. The idea is that there will be only one json file with schema for wheels and different features will use it in response validations. How I can do the same thing in json file? – cygne Oct 10 '17 at 15:51
  • JSON keys are not dynamic – cygne Oct 10 '17 at 16:01
  • please could you help us? I edited the question to make it easier to understand – cygne Oct 27 '17 at 15:14
  • I think your edit makes it harder to understand :P what is your expected behavior ? Karate has no support for "oneOf" in case that is what you are expecting. In other words, Karate has no support for JSON schema directly. Look at this example if you want to use JSON schema via a Java library: https://github.com/intuit/karate/blob/master/karate-demo/src/test/java/demo/schema/schema.feature – Peter Thomas Oct 27 '17 at 16:14