Spring MVC 测试中带有过滤器的 JsonPath 表达式
JsonPath expression with filters in Spring MVC test
我有一个控制器 returns 部分列表。这些部分中的每一个都有一个类型。我想测试类型 "JOB" 的部分是否有一个字段 "functions",大小为 3.
这是我的代码:
mockMvc.perform(get(url)
.contentType(MediaTypes.HAL_JSON)
.accept(MediaTypes.HAL_JSON))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.content",
hasSize(equalTo(2))))
.andExpect(jsonPath("$._embedded.content[?(@.type=='JOB')].functions",
hasSize(equalTo(3))));
控制器返回的JSON(为便于阅读而简化):
{
"_embedded":{
"content":[
{
"subsections":null,
"type":"PROFILE",
"createdDate":null,
"lastModifiedDate":null
},
{
"functions":[
{
"rank":845131,
"function":"9IXZT"
},
{
"rank":82701,
"function":"T91WX"
},
{
"rank":98686,
"function":"PA7NA"
}
],
"type":"JOB",
"createdDate":null,
"lastModifiedDate":null
}
]
}
}
我用 this tool 和那个 JSON 测试了表达式并且工作正常,但是当 运行 测试时我得到这个断言错误:
java.lang.AssertionError: JSON path "$._embedded.content[?(@.type=='JOB')].functions"
Expected: a collection with size <3>
but: collection size was <1>
at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20)
at org.springframework.test.util.JsonPathExpectationsHelper.assertValue(JsonPathExpectationsHelper.java:74)
at org.springframework.test.web.servlet.result.JsonPathResultMatchers.match(JsonPathResultMatchers.java:86)
at org.springframework.test.web.servlet.MockMvc.andExpect(MockMvc.java:171)
...
在表达式末尾添加 .* 解决了问题,所以现在看起来像这样:
$._embedded.content[?(@.type=='JOB')].functions.*
我不明白为什么示例中的第一个表达式有效,但我必须将 .* 添加到第二个表达式。如果有人知道,请解释一下。
添加 .*
时有所不同。当我在 JSONPath Expression Tester 处填写你的数据时
我得到一个细微但重要的区别:
案例一
$._embedded.content[?(@.type=='JOB')].functions
产量
[
[
{
"rank":845131,
"function":"9IXZT"
},
{
"rank":82701,
"function":"T91WX"
},
{
"rank":98686,
"function":"PA7NA"
}
]
]
案例二
和$._embedded.content[?(@.type=='JOB')].functions.*
产量
[
{
"rank":845131,
"function":"9IXZT"
},
{
"rank":82701,
"function":"T91WX"
},
{
"rank":98686,
"function":"PA7NA"
}
]
因此对于情况 1,当您采用根节点(它是一个数组)时,您有 一个元素 作为直接子元素:包含三个对象的数组。因此,断言找到了一个大小为 1 的数组(集合)。
对于情况 2,您的数组根节点 包含三个对象 导致集合计数为三个。
也许其他实现方式并非如此。在这个例子中,我使用了 JSONPath 0.3.4 在 Flow Communications 下的实现。
functions
后的.
将结果的根层级设置为本元素而*
表示取本根下的所有元素 .
我没有足够的信心来解释 $._embedded.content[?(@.type=='JOB')].functions
背后的确切行为。不过我觉得跟滤镜有关系?(@.type=='JOB')
我有一个控制器 returns 部分列表。这些部分中的每一个都有一个类型。我想测试类型 "JOB" 的部分是否有一个字段 "functions",大小为 3.
这是我的代码:
mockMvc.perform(get(url)
.contentType(MediaTypes.HAL_JSON)
.accept(MediaTypes.HAL_JSON))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.content",
hasSize(equalTo(2))))
.andExpect(jsonPath("$._embedded.content[?(@.type=='JOB')].functions",
hasSize(equalTo(3))));
控制器返回的JSON(为便于阅读而简化):
{
"_embedded":{
"content":[
{
"subsections":null,
"type":"PROFILE",
"createdDate":null,
"lastModifiedDate":null
},
{
"functions":[
{
"rank":845131,
"function":"9IXZT"
},
{
"rank":82701,
"function":"T91WX"
},
{
"rank":98686,
"function":"PA7NA"
}
],
"type":"JOB",
"createdDate":null,
"lastModifiedDate":null
}
]
}
}
我用 this tool 和那个 JSON 测试了表达式并且工作正常,但是当 运行 测试时我得到这个断言错误:
java.lang.AssertionError: JSON path "$._embedded.content[?(@.type=='JOB')].functions"
Expected: a collection with size <3>
but: collection size was <1>
at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20)
at org.springframework.test.util.JsonPathExpectationsHelper.assertValue(JsonPathExpectationsHelper.java:74)
at org.springframework.test.web.servlet.result.JsonPathResultMatchers.match(JsonPathResultMatchers.java:86)
at org.springframework.test.web.servlet.MockMvc.andExpect(MockMvc.java:171)
...
在表达式末尾添加 .* 解决了问题,所以现在看起来像这样:
$._embedded.content[?(@.type=='JOB')].functions.*
我不明白为什么示例中的第一个表达式有效,但我必须将 .* 添加到第二个表达式。如果有人知道,请解释一下。
添加 .*
时有所不同。当我在 JSONPath Expression Tester 处填写你的数据时
我得到一个细微但重要的区别:
案例一
$._embedded.content[?(@.type=='JOB')].functions
产量
[
[
{
"rank":845131,
"function":"9IXZT"
},
{
"rank":82701,
"function":"T91WX"
},
{
"rank":98686,
"function":"PA7NA"
}
]
]
案例二
和$._embedded.content[?(@.type=='JOB')].functions.*
产量
[
{
"rank":845131,
"function":"9IXZT"
},
{
"rank":82701,
"function":"T91WX"
},
{
"rank":98686,
"function":"PA7NA"
}
]
因此对于情况 1,当您采用根节点(它是一个数组)时,您有 一个元素 作为直接子元素:包含三个对象的数组。因此,断言找到了一个大小为 1 的数组(集合)。 对于情况 2,您的数组根节点 包含三个对象 导致集合计数为三个。
也许其他实现方式并非如此。在这个例子中,我使用了 JSONPath 0.3.4 在 Flow Communications 下的实现。
functions
后的.
将结果的根层级设置为本元素而*
表示取本根下的所有元素 .
我没有足够的信心来解释 $._embedded.content[?(@.type=='JOB')].functions
背后的确切行为。不过我觉得跟滤镜有关系?(@.type=='JOB')