How to validate with yml file a karate structure response

Viewed 231

recently I started working with Karate and Yaml for the first time. I was able to validate simple response structures where all the answer data were on the same level. But now I have to validate a more complicated structure and I spent a lot of time without success.

When I perform a GET request I receive the next answer:

[
    {
        "factories": [
            {
                "id": 1,
                "scopes": [
                    {
                        "id": null,
                        "name": "name 1",
                        "expireD": 10,
                        "isExpired": true
                    }
                ],
                "companyName": "TEST",
            },
            {
                "id": 2,
                "scopes": [
                    {
                        "id": null,
                        "name": "name 2",
                        "expireD": 7,
                        "isExpired": true
                    }
                ],
                "companyName": "TEST2",
            }
        ],
        "scopeId": null
    }
]

The structure validation is not directly in the karate code. It is on a yml file like this:

operationId: getTest
statusCode: 200
params:
body: null
matchResponse: true
responseMatches:
  scopeId: '##number'
  factories:
    companyName: '#string'
    id: '#number'
    scopes:
      expireD: '#number'
      name: '#string'
      id: '#null'
      isExpired: '#boolean'

I review the structure around 100 times and I have the same error all the time when I arrive here:

* match response contains responseMatches

The error is the next one: $[1].factories | data types don't match (LIST:MAP)

I tried to use match each, ignore one by one the structures to see which one is failing and also reduce the validations as #array and it is not working.

Any help will be more than welcome. Thank you.

2 Answers

I really recommend NOT using YAML especially in a testing / validation scenario. But finally it is your call.

Here is a tip to save you some time, you can print out the value of the YAML and see where you were going wrong. I don't know YAML (and avoid it as far as possible), but I made a guess after a few failed attempts and managed to insert a - at the right place (apparently there are many other ways) to make some of the YAML a JSON array - which is what you want.

* text foo =
"""
operationId: getTest
statusCode: 200
params:
body: null
matchResponse: true
responseMatches:
  scopeId: '##number'
  factories:
    -
      companyName: '#string'
      id: '#number'
      scopes:
        expireD: '#number'
        name: '#string'
        id: '#null'
        isExpired: '#boolean'
"""
* yaml foo = foo
* print foo

Try the above and see how it differs from your example.

Finally, a solution was found. The Karate documentation offers an idea about how to use it defining a structure of data that could be used as a type. I tried before but I added before the responseMatches section. The yml file looks like this:

operationId: getTest
statusCode: 200
params:
body: null
matchResponse: true
responseMatches:
  scopeId: '##number'
  factories: '#[_ <= 5] factoryStructure'

factoryStructure:
    companyName: '#string'
    id: '#number'
    scopes: '#[] scopeStructure'

scopesStructure:
  expireD: '#number'
  name: '#string'
  id: '#null'
  isExpired: '#boolean'
Related