1

I have a rest json response that contains an array and I would like to write tests for it. Sadly, it comes unordered so I can't rely on a specific order of the array's content. How should I test the matching information together?

It looks like something like this:

{
  "context": "school",
  "students": [
    {
      "id": "1",
      "name": "Alice",
      "address": {
        "city": "London",
        "street": "Big Street 1"
      } 
    },
    {
      "id": "2",
      "name": "Bob",
      "address": {
        "city": "Manchester",
        "street": "Little Street 2"
      } 
    }
  ]
}

I have tried this so far:

//...

getMockMvc().perform(get("/students"))
            .andExpect(status().isOk())
            .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
            .andExpect(jsonPath("$.students[*].id", containsInAnyOrder("1, 2")))
            .andExpect(jsonPath("$.students[*].name", containsInAnyOrder("Alice", "Bob")))
            .andExpect(jsonPath("$students[*].address.city", containsInAnyOrder("London", "Manchester");

// ... other parts of code

The problem is that my students array can be in any order. And now this solution does not make sure that I can test the cohesive information together.

How should I achieve this?

Five
  • 378
  • 2
  • 19
  • first of all, any reason you need to fixate on json path? Can you not parse you own matcher in expect? – Sagar Kharab Mar 25 '22 at 16:54
  • @Sagar Kharab I'm pretty unsure, I have never done anything like this before. I guess I can write my own matcher. Do you have any tips on how should I start? – Five Mar 25 '22 at 17:00
  • since you know the response already you can filter the response once confirmed the names are matching https://stackoverflow.com/questions/47576119/jsonpath-filter-by-value-in-array – Sagar Kharab Mar 25 '22 at 17:08

1 Answers1

0

How about creating a class that matches the Json. Then you can the class to test what you want more easily.

@Data
private class School {
    String context;
    List<Student> students;
}

@Data
private class Student {
    String id;
    String name;
    Address address;
}

@Data
private class Address {
    String city;
    String street;

And you can test this using assertJ like this

school.getStudents().stream().map(student -> student.id).forEach(id -> assertThat(id).isIn("1", "2"));
school.getStudents().stream().map(student -> student.name).forEach(name -> assertThat(name).isIn("Alice", "Bob"));
school.getStudents().stream().map(student -> student.address.city).forEach(city -> assertThat(city).isIn("London", "Manchester"));
Seon Woo Kim
  • 58
  • 2
  • 6