使用JSONpath验证是否存在根节点数组

时间:2017-11-17 13:24:44

标签: java json rest hamcrest

从下面的JSON响应中,我可以使用hamcrest库中的此方法验证JSONpath中是否存在根节点:

assertThat(json, hasJsonPath("$.tool"));

这会检查根节点是否已调用' tool'存在。

{
    "tool": 
    {
        "jsonpath": 
        {
            "creator": 
            {
                "name": "Jayway Inc.",
                "location": 
                [
                    "Malmo",
                    "San Francisco",
                    "Helsingborg"
                ]
            }
        }
    },

    "book": 
    [
        {
            "title": "Beginning JSON",
            "price": 49.99
        },

        {
            "title": "JSON at Work",
            "price": 29.99
        }
    ]
}

如果我想使用存储在变量中的数组检查两个根节点(工具和书)的存在,如何实现?我并不关心它们的值或子节点的值。我只是想验证响应中是否存在这两个根节点,并且它们是有效的路径。

将我的API响应在“json”中串起来后#39;变量我试过这样的事情:

JsonPath jp = new JsonPath(json);

String[] rootNodes = {"tool", "book"};
assertThat(json, hasJsonPath(json.getString(rootNodes)));

但编译器对getString方法不满意。

有没有办法解决这个问题?

1 个答案:

答案 0 :(得分:1)

根节点运算符为$,因此您只需将$读入地图,该地图将以您的根节点名称为基础。

例如:

// Approach 1
Map<String, Object> read = JsonPath.read(json, "$");

assertThat(read.size(), is(2));

assertThat(read.keySet(), hasItem("tool"));
assertThat(read.keySet(), hasItem("book"));

// Approach 2: if you want a String[] then ...
String[] rootNodeNames = read.keySet().toArray(new String[read.size()]);
assertThat(rootNodeNames, Matchers.both(arrayWithSize(2)).and(arrayContainingInAnyOrder("book", "tool")));

// Approach 3: if you want to hide it all behind the hasJsonPath() matcher
// note: each of these assertion will cause your JSON string to be parsed 
// so it's more efficient to do that once and assert against the 
// resulting map as I did above
assertThat(json, hasJsonPath("$", Matchers.hasKey("tool")));
assertThat(json, hasJsonPath("$", Matchers.hasKey("book")));