用于查找字段顺序的JSONPath表达式的匹配器

时间:2017-12-08 17:04:50

标签: java jsonpath hamcrest mockmvc spring-mvc-test

我有一个API,它返回一个将在UI中显示的JSON对象。对象中字段的顺序很重要,因为UI希望按该顺序显示字段。我想编写一个单元测试来确保对象中字段的顺序是正确的。我的API响应如下所示:

{
    "data": {
        "field1": "value1",
        "field2": "value2"
     }
}

使用spring boot的MockMvc库,我想写一个这样的表达式来验证字段是按顺序返回的:

.andExpect(jsonPath("$.data"), is("field1=value1, field2=value2")

显然,上述内容并不奏效,但我不确定我应该使用哪种类型的Matcher来验证字段是否有序。

1 个答案:

答案 0 :(得分:0)

我无法找到一个Hamcrest匹配器来比较字段的顺序,但是编写自己的很容易。请注意,JSON路径表达式的结果将为您提供LinkedHashMap,因此您只需要一个匹配LinkedHashMap并将其与给定对象进行比较的匹配器,按顺序逐条输入。将地图转换为List条目并使用equals List方法可以解决问题,因为List会按顺序比较项目。

以下是匹配器的外观:

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());
    }
}

以下是断言的样子:

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)));