如何从org.springframework.test.web.servlet.ResultActions中提取显式内容

时间:2015-12-27 11:20:26

标签: java json unit-testing spring-mvc spring-test

我正在通过样本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

所以,我认为系统希望报告错误的路径,但找不到异常的类。所以,我包含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",
}

1 个答案:

答案 0 :(得分:2)

我这样做:

// 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包装器(**)。触发AssignmentResultHandlerhandle运行, 它设置了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;
    } 
}