如何从 org.springframework.test.web.servlet.ResultActions 中提取露骨内容
How to extract explicit content from org.springframework.test.web.servlet.ResultActions
我正在按示例编写测试 from here。该测试旨在检查 root 的用户名是否等于它在数据库中的用户名并查看以下内容:
import static org.junit.Assert.*;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.webAppContextSetup;
...
@Test
public void rootUserPresent() throws Exception {
ResultActions result = mockMvc.perform(get("/user/root"));
result
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$.screenName", is(userRepository.getRootUser().getScreenName())))
;
}
首先我写了这个测试,它导致了 ClassNotFound 异常
java.lang.NoClassDefFoundError: com/jayway/jsonpath/InvalidPathException
所以,我在想系统希望向我报告错误路径但找不到 class 异常。因此,我包含了 com.jayway.jsonpath:json-path-assert:1.1.0
依赖项。之后测试就开始通过了。
所以,我开始怀疑,那个检测结果是错误的阳性。
我的问题是:如何使用我在这里使用的相同工具明确提取 JSON 值,并按字面检查它的值?
PS
JSON 结果如下:
{
id: 1,
roles: [
{
name: "USER"
},
{
name: "ADMIN"
}
],
firstName: null,
lastName: null,
screenName: "root",
}
我是这样做的:
// wrapper to extract result from the response
AssignmentResult result = new AssignmentResult();
// perform request
mockMvc.perform(
get("/myApiEndpoint")
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
)
.andExpect(status().isOk())
.andExpect(jsonPath("$object.parent.id", is(parent.getId())))
.andDo(assignTo("$object.id", result)); // (**)
Integer objectIdFromResult = (Integer)result.getValue(); // (++)
assignTo
是我写的自定义 ResultHandler:
/**
* Spring ResultHandler for MVC testing, allows the assignment of a JSON path to a variable.
*/
public class AssignmentResultHandler implements ResultHandler {
private final JsonPath jsonPath;
private final AssignmentResult assignmentResult;
public static ResultHandler assignTo(String jsonPath, AssignmentResult assignmentResult) {
return new AssignmentResultHandler(JsonPath.compile(jsonPath), assignmentResult);
}
protected AssignmentResultHandler(JsonPath jsonPath, AssignmentResult assignmentResult) {
this.jsonPath = jsonPath;
this.assignmentResult = assignmentResult;
}
@Override
public void handle(MvcResult result) throws Exception {
String resultString = result.getResponse().getContentAsString();
assignmentResult.setValue(jsonPath.read(resultString));
}
}
创建新的 AssignmentResultHandler
时,您传入一个 AssignmentResult
包装器 (**)。当 AssignmentResultHandler
被触发时(handle
运行),
它设置 AssignmentResult
的值。请求完成后,您可以从那里解包值 (++)。
这是 AssignmentResult 包装器:
public class AssignmentResult {
private Object value;
/**
* Set the result value
* @param value result value
*/
protected void setValue(Object value) {
this.value = value;
}
/**
* Returns the result value
* @return the result value
*/
public Object getValue() {
return this.value;
}
}
我正在按示例编写测试 from here。该测试旨在检查 root 的用户名是否等于它在数据库中的用户名并查看以下内容:
import static org.junit.Assert.*;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.webAppContextSetup;
...
@Test
public void rootUserPresent() throws Exception {
ResultActions result = mockMvc.perform(get("/user/root"));
result
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$.screenName", is(userRepository.getRootUser().getScreenName())))
;
}
首先我写了这个测试,它导致了 ClassNotFound 异常
java.lang.NoClassDefFoundError: com/jayway/jsonpath/InvalidPathException
所以,我在想系统希望向我报告错误路径但找不到 class 异常。因此,我包含了 com.jayway.jsonpath:json-path-assert:1.1.0
依赖项。之后测试就开始通过了。
所以,我开始怀疑,那个检测结果是错误的阳性。
我的问题是:如何使用我在这里使用的相同工具明确提取 JSON 值,并按字面检查它的值?
PS
JSON 结果如下:
{
id: 1,
roles: [
{
name: "USER"
},
{
name: "ADMIN"
}
],
firstName: null,
lastName: null,
screenName: "root",
}
我是这样做的:
// wrapper to extract result from the response
AssignmentResult result = new AssignmentResult();
// perform request
mockMvc.perform(
get("/myApiEndpoint")
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
)
.andExpect(status().isOk())
.andExpect(jsonPath("$object.parent.id", is(parent.getId())))
.andDo(assignTo("$object.id", result)); // (**)
Integer objectIdFromResult = (Integer)result.getValue(); // (++)
assignTo
是我写的自定义 ResultHandler:
/**
* Spring ResultHandler for MVC testing, allows the assignment of a JSON path to a variable.
*/
public class AssignmentResultHandler implements ResultHandler {
private final JsonPath jsonPath;
private final AssignmentResult assignmentResult;
public static ResultHandler assignTo(String jsonPath, AssignmentResult assignmentResult) {
return new AssignmentResultHandler(JsonPath.compile(jsonPath), assignmentResult);
}
protected AssignmentResultHandler(JsonPath jsonPath, AssignmentResult assignmentResult) {
this.jsonPath = jsonPath;
this.assignmentResult = assignmentResult;
}
@Override
public void handle(MvcResult result) throws Exception {
String resultString = result.getResponse().getContentAsString();
assignmentResult.setValue(jsonPath.read(resultString));
}
}
创建新的 AssignmentResultHandler
时,您传入一个 AssignmentResult
包装器 (**)。当 AssignmentResultHandler
被触发时(handle
运行),
它设置 AssignmentResult
的值。请求完成后,您可以从那里解包值 (++)。
这是 AssignmentResult 包装器:
public class AssignmentResult {
private Object value;
/**
* Set the result value
* @param value result value
*/
protected void setValue(Object value) {
this.value = value;
}
/**
* Returns the result value
* @return the result value
*/
public Object getValue() {
return this.value;
}
}