Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Testing jsonpath that array contains specfic objects in any order

I'm testing a Spring controller which can give back a 400 with field errors. These field errors is an array of objects containing a "path" and "message" field.

Now I want to test that some specific call returns multiple errors with specific path and message.

I cannot come to anything closer then below:

.andExpect(jsonPath("$.fieldErrors[*].path", containsInAnyOrder("title", "description")))
.andExpect(jsonPath("$.fieldErrors[*].message", containsInAnyOrder(
    "The maximum length of the description is 500 characters.",
    "The maximum length of the title is 100 characters.")));

But this keeps the option open that bad combinations of "path" and "message" is accepted.

Any ideas how to improve the jsonpath to test this?

like image 453
Marcel Overdijk Avatar asked Oct 21 '14 07:10

Marcel Overdijk


2 Answers

This seems to the better approach:

.andExpect(jsonPath('$.fieldErrors[?(@.path == \'title\' && @.message == \'The maximum length of the title is 100 characters.\')]').exists())
like image 98
Marcel Overdijk Avatar answered Sep 19 '22 05:09

Marcel Overdijk


Just expanding on the answer provided by Marcel, as it helped me solve the same issue but I had to modify slightly. I found that the '&&' operator wasn't supported in the version of jsonpath we currently use in one project (0.8.1), according to this issue it was marked as 'done' on Dec 8th which implies it should be available in the latest version, 2.0:

JSON Path issue 27 - AND operators

The 'old' syntax for logical AND which I ended up using is also shown on that issue and using the example above would be:

.andExpect(jsonPath('$.fieldErrors[?(@.path == \'title\')][?(@.message == \'The maximum length of the title is 100 characters.\')]').exists())
like image 29
Tom Bunting Avatar answered Sep 22 '22 05:09

Tom Bunting