Nested iteration over JSON using groovy closure in REST-assured

Deadly 提交于 2019-12-23 03:09:46

问题


I have the following JSON response for my REST endpoint:

{
  "response": {
    "status": 200,
    "startRow": 0,
    "endRow": 1,
    "totalRows": 1,
    "next": "",
    "data": {
      "id": "workflow-1",
      "name": "SampleWorkflow",
      "tasks": [
        {
          "id": "task-0",
          "name": "AWX",
          "triggered_by": ["task-5"]
        },
        {
          "id": "task-1",
          "name": "BrainStorming",
          "triggered_by": ["task-2", "task-5"]
        },
        {
          "id": "task-2",
          "name": "OnHold",
          "triggered_by": ["task-0", "task-4", "task-7", "task-8", "task9"]
        },
        {
          "id": "task-3",
          "name": "InvestigateSuggestions",
          "triggered_by": ["task-6"]
        },
        {
          "id": "task-4",
          "name": "Mistral",
          "triggered_by": ["task-3"]
        },
        {
          "id": "task-5",
          "name": "Ansible",
          "triggered_by": ["task-3"]
        },
        {
          "id": "task-6",
          "name": "Integration",
          "triggered_by": []
        },
        {
          "id": "task-7",
          "name": "Tower",
          "triggered_by": ["task-5"]
        },
        {
          "id": "task-8",
          "name": "Camunda",
          "triggered_by": ["task-3"]
        },
        {
          "id": "task-9",
          "name": "HungOnMistral",
          "triggered_by": ["task-0", "task-7"]
        },
        {
          "id": "task-10",
          "name": "MistralIsChosen",
          "triggered_by": ["task-1"]
        }
      ]
    }
  }
}

I am using rest-assured with a groovy gpath expression for an extraction as follows:

given()
.when()
.get("http://localhost:8080/workflow-1")
.then()
.extract()
.path("response.data.tasks.findAll{ it.triggered_by.contains('task-3') }.name")

which correctly gives me [Mistral, Ansible, Camunda]

What I am trying to achieve is to find the task names that are triggered by the InvestigateSuggestions task. But I don't know for sure that the taskId I have to pass in to contains() is task-3; I only know its name i.e. InvestigateSuggestions. So I attempt to do:

given()
.when()
.get("http://localhost:8080/workflow-1")
.then()
.extract()
.path("response.data.tasks.findAll{ 
    it.triggered_by.contains(response.data.tasks.find{
    it.name.equals('InvestigateSuggestions')}.id) }.name")

which does not work and complains that the parameter "response" was used but not defined.

How do I iterate over the outer collection from inside the findAll closure to find the correct id to pass into contains() ??


回答1:


You can make use of a dirty secret, the restAssuredJsonRootObject. This is undocumented (and subject to change although it has never change as far as I can remember in the 7 year+ lifespan of REST Assured).

This would allow you to write:

given()
.when()
.get("http://localhost:8080/workflow-1")
.then()
.extract()
.path("response.data.tasks.findAll{ 
    it.triggered_by.contains(restAssuredJsonRootObject.response.data.tasks.find{
    it.name.equals('InvestigateSuggestions')}.id) }.name")

If you don't want to use this "hack" then you need to do something similar to what Michael Easter proposed in his answer.

When it comes to generating matchers based on the response body the story is better. See docs here.




回答2:


I'm not sure if this is idiomatic but one approach is to find the id first and then substitute into another query:

@Test
void testCase1() {
    def json = given()
    .when()
    .get("http://localhost:5151/egg_minimal/stacko.json")

    // e.g. id = 'task-3' for name 'InvestigateSuggestions'

    def id = json
    .then()
    .extract()
    .path("response.data.tasks.find { it.name == 'InvestigateSuggestions' }.id")

    // e.g. tasks have name 'task-3'

    def tasks = json
    .then()
    .extract()
    .path("response.data.tasks.findAll{ it.triggered_by.contains('${id}') }.name")

    assertEquals(['Mistral', 'Ansible', 'Camunda'], tasks)
}


来源:https://stackoverflow.com/questions/52122487/nested-iteration-over-json-using-groovy-closure-in-rest-assured

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!