Reputation: 31
I have an API that returns a JSON object that will be displayed in a UI. The order of the fields in the object matters because the UI wants to display the fields in that order. I want to write a unit test to ensure the order of the fields in the object is correct. My API response looks like this:
{
"data": {
"field1": "value1",
"field2": "value2"
}
}
Using spring boot's MockMvc
library, I want to write an expression like this to validate that the fields are coming back in order:
.andExpect(jsonPath("$.data"), is("field1=value1, field2=value2")
Obviously, the above doesn't work but I'm not sure what type of Matcher
I should be using to try and validate that the fields are in order.
Upvotes: 2
Views: 2659
Reputation: 31
I couldn't find a Hamcrest matcher that compares the order of the fields, but it is easy enough to write your own. Note that the result of the JSON path expression will give you a LinkedHashMap
so all you need is a Matcher that takes in a LinkedHashMap
and compares it to the given object, entry by entry in order. Converting the map to a List
of entries and using the equals
method of List
does the trick since List
will compare items in order.
Here's how the matcher looks:
private class OrderedMapMatcher extends BaseMatcher<Map<String, String>> {
private LinkedHashMap<String, String> expected;
public OrderedMapMatcher(LinkedHashMap<String, String> expected) {
this.expected = expected;
}
@Override
public boolean matches(Object o) {
if (!(o instanceof LinkedHashMap)) {
return false;
}
LinkedHashMap actual = (LinkedHashMap) o;
List<Map.Entry<String, String>> expectedList = new ArrayList<>(expected.entrySet());
List actualList = new ArrayList(actual.entrySet());
return expectedList.equals(actualList);
}
@Override
public void describeTo(Description description) {
description.appendText(expected.toString());
}
}
And here's how the assertion looks:
LinkedHashMap<String, String> expectedData = new LinkedHashMap<>();
expectedData.put("field1", "value1");
expectedData.put("field2", "value2");
// mockMvc ResultActions code would be here
.andExpect(jsonPath("$.data", new OrderedMapMatcher(expectedData)));
Upvotes: 1