java junit 测试中的 MockMVC - 检查 List<Object> 和 Map<Enum, Object> 的结果
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/46885972/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
MockMVC in junit tests - checking result for List<Object> and Map<Enum, Object>
提问by xross
I have problems with mockMVC and test written with that. My tests fails. I have two tests methods:
我对 mockMVC 和用它编写的测试有问题。我的测试失败了。我有两种测试方法:
@Test
public void getPersonsForApiConsumerTest() throws Exception {
mockMvc.perform(get(getUri("/consumers/1/persons")))
.andExpect(status().isOk())
.andExpect(jsonPath("$", hasSize(2)))
.andExpect(jsonPath("$[1].name", is("Ligza")))
.andExpect(jsonPath("$[2].name", is("Vekrir")));
}
@Test
public void getPersonsForApiConsumerMapTest() throws Exception {
mockMvc.perform(get(getUri("/consumers/1/persons/map")))
.andExpect(status().isOk())
.andExpect(jsonPath("$[1].name", is("Verkir")))
.andExpect(jsonPath("$[2].name", is("Ligza")));
}
Rest methods with mapping:
带有映射的休息方法:
@RequestMapping(value = "/{consumerId}/persons")
public List<PersonDto> getPersonsForApiConsumer(@PathVariable("consumerId") Integer consumerId) throws IOException {
return apiConsumerService.getPersonsListForApiConsumer(consumerId);
}
@RequestMapping(value = "/{consumerId}/persons/map")
public Map<ApiConsumerPersonRole, List<Person>> getPersonsForApiConsumerMap(@PathVariable("consumerId") Integer consumerId) throws IOException {
return apiConsumerService.getPersonsMapForApiConsumer(consumerId);
}
By Postman I can gain data such:
通过邮递员,我可以获得以下数据:
for list:
清单:
[
{
"id": 1,
"firstName": "Ligza",
"lastName": "Zetasor",
"role": "REPRESENTATIVE",
"phone": "123123123",
"email": "[email protected]"
},
{
"id": 4,
"firstName": "Vekrir",
"lastName": "Omegaram",
"role": "SECURITY_OFFICER",
"phone": "354654545",
"email": "[email protected]"
}
]
for map:
地图:
{
"SECURITY_OFFICER": [
{
"id": 4,
"firstName": "Vekrir",
"lastName": "Omegaram",
"telephone": "354654545",
"email": "[email protected]"
}
],
"REPRESENTATIVE": [
{
"id": 1,
"firstName": "Ligza",
"lastName": "Zetasor",
"telephone": "123123123",
"email": "[email protected]"
}
],
"COMPLAINT_OFFICER": [],
"LOCAL_REPRESENTATIVE": []
}
I dont have any clue how to write it properly. I want to check the data inside this list and map.
我不知道如何正确编写它。我想检查这个列表和地图中的数据。
Is it possible to stream it into that collection or check it easily in the way it is wriiten already?
是否可以将其流式传输到该集合中或以已经编写的方式轻松检查它?
Edit: logs:
编辑:日志:
java.lang.AssertionError: No value at JSON path "$[1].firstname", exception: No results for path: $[1]['firstname']
at org.springframework.test.util.JsonPathExpectationsHelper.evaluateJsonPath(JsonPathExpectationsHelper.java:245)
at org.springframework.test.util.JsonPathExpectationsHelper.assertValue(JsonPathExpectationsHelper.java:73)
at org.springframework.test.web.servlet.result.JsonPathResultMatchers.match(JsonPathResultMatchers.java:87)
at org.springframework.test.web.servlet.MockMvc.andExpect(MockMvc.java:171)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
at org.junit.runners.ParentRunner.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access.andExpect(jsonPath("$[0].firstName", is("Ligza")))
.andExpect(jsonPath("$[1].firstName", is("Vekrir")))
0(ParentRunner.java:58)
at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Process finished with exit code -1
MockHttpServletResponse:
Status = 200
Error message = null
Headers = {X-Content-Type-Options=[nosniff], X-XSS-Protection=[1; mode=block], Cache-Control=[no-cache, no-store, max-age=0, must-revalidate], Pragma=[no-cache], Expires=[0], X-Frame-Options=[DENY], Content-Type=[application/json;charset=UTF-8]}
Content type = application/json;charset=UTF-8
Body = {"COMPLAINT_OFFICER":[],"REPRESENTATIVE":[{"id":1,"firstName":"Ligza","lastName":"Zetasor","telephone":"123123123","email":"[email protected]"}],"LOCAL_REPRESENTATIVE":[],"SECURITY_OFFICER":[{"id":4,"firstName":"Vekrir","lastName":"Omegaram","telephone":"354654545","email":"[email protected]"}]}
Forwarded URL = null
Redirected URL = null
Cookies = []
java.lang.AssertionError: No value at JSON path "$[1].firstname", exception: Filter: [1]['firstname'] can only be applied to arrays. Current context is: {COMPLAINT_OFFICER=[], REPRESENTATIVE=[{"id":1,"firstName":"Ligza","lastName":"Zetasor","telephone":"123123123","email":"[email protected]"}], LOCAL_REPRESENTATIVE=[], SECURITY_OFFICER=[{"id":4,"firstName":"Vekrir","lastName":"Omegaram","telephone":"354654545","email":"[email protected]"}]}
at org.springframework.test.util.JsonPathExpectationsHelper.evaluateJsonPath(JsonPathExpectationsHelper.java:245)
at org.springframework.test.util.JsonPathExpectationsHelper.assertValue(JsonPathExpectationsHelper.java:73)
at org.springframework.test.web.servlet.result.JsonPathResultMatchers.match(JsonPathResultMatchers.java:87)
at org.springframework.test.web.servlet.MockMvc.andExpect(MockMvc.java:171)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
at org.junit.runners.ParentRunner.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.accessMvcResult result = mockMvc.perform(get(getUri("/consumers/1/persons")))
.andExpect(status().isOk())
.andReturn();
ObjectMapper mapper = new ObjectMapper();
// this uses a TypeReference to inform Hymanson about the Lists's generic type
List<PersonDto> actual = mapper.readValue(result.getResponse().getContentAsString(), new TypeReference<List<PersonDto>>() {});
// now just assert equality (or whatever) against the actual PersonDto
0(ParentRunner.java:58)
at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
回答by glytching
The jsonPath
helpers are very useful for asserting your responses are valid from the perspective of the consumers of your API; these consumers receive a JSON repsonse so it makes sense to perform your assertions on that JSON.
该jsonPath
助手是断言你的反应是从消费者的API的角度有效非常有用的; 这些消费者会收到一个 JSON 响应,因此在该 JSON 上执行您的断言是有意义的。
The following assertions will work for the payload from /consumers/1/persons
以下断言适用于来自 /consumers/1/persons
So, the array is 0-based and you access entries in each element by the (case sensitive) name.
因此,该数组是基于 0 的,您可以通过(区分大小写)名称访问每个元素中的条目。
However, if you really want to assert against the original types (e.g. PersonDto
) then you can read the entire JSON string and use a JSON mapper (such as Hymansonor Gson) to deserialize it back into its original class representation. For example:
但是,如果您真的想针对原始类型(例如PersonDto
)进行断言,那么您可以读取整个 JSON 字符串并使用 JSON 映射器(例如Hymanson或Gson)将其反序列化回其原始类表示。例如: