Laravel HTTP Test using getJson + assertJsonStructure array of objects

Viewed 975

I have a Laravel 8 application where I want to test a part of the JSON that's returned from an HTTP API call. My response object looks like the following:

{
    "data": [
        {
            "name": "Cumque ex quos.",
            "createdAt": "2020-12-29T17:15:32.000000Z",
            "updatedAt": "2020-12-29T17:15:32.000000Z",
            "startAt": "2021-01-18 17:15:32",
            "endAt": "2021-01-18 17:15:32",
            "startedAt": null,
            "status": "Running",
            "range": {
                "type": "percentage",
                "max": 0,
                "min": 0
            },
        },
        {
            "name": "Cumque ex quos 2.",
            "createdAt": "2020-12-29T17:15:32.000000Z",
            "updatedAt": "2020-12-29T17:15:32.000000Z",
            "startAt": "2021-01-18 17:15:32",
            "endAt": "2021-01-18 17:15:32",
            "startedAt": null,
            "status": "Pending",
            "range": {
                "type": "percentage",
                "max": 20,
                "min": 100
            },
        },
    ],
    "other_keys" [ ... ];
}

I am interested in testing the structure of the array returned by the data key. Here is the test I am using that is failing:

 /** @test */
    public function should_get_data_and_validate_the_structure()
    {
        $this->withoutExceptionHandling();

        $response = $this->getJson('/api/v1/data');

        $response->assertJsonStructure([
            'data' => [
                'createdAt',
                'endAt',
                'name',
                'startAt',
                'startedAt',
                'status',
                'updatedAt',
                'range' => [
                    'max',
                    'min',
                    'type'
                ],           
            ]
        ]);
    }

The test fails with the following error: Failed asserting that an array has the key 'createdAt'.

1 Answers

data is an array, therefore, to assert the structure of a nested object we need to use the * wildcard:

$response->assertJsonStructure([
   'data' => [
         '*' => [
            'createdAt',
            'endAt',
            'name',
            'startAt',
            'startedAt',
            'status',
            'updatedAt',
            'range' => [
                'max',
                'min',
                'type'
            ],
        ]
      ]
]);
Related