我有简单的积分测试

@Test
public void shouldReturnErrorMessageToAdminWhenCreatingUserWithUsedUserName() throws Exception {
    mockMvc.perform(post("/api/users").header("Authorization", base64ForTestUser).contentType(MediaType.APPLICATION_JSON)
        .content("{\"userName\":\"testUserDetails\",\"firstName\":\"xxx\",\"lastName\":\"xxx\",\"password\":\"xxx\"}"))
        .andDo(print())
        .andExpect(status().isBadRequest())
        .andExpect(?);
}

在最后一行中,我想比较在响应体中接收到的字符串与预期的字符串

我得到的回答是:

MockHttpServletResponse:
          Status = 400
   Error message = null
         Headers = {Content-Type=[application/json]}
    Content type = application/json
            Body = "Username already taken"
   Forwarded URL = null
  Redirected URL = null

尝试了content(), body()的一些技巧,但都不起作用。


当前回答

Spring security的@WithMockUser和hamcrest的containsString匹配器提供了一个简单而优雅的解决方案:

@Test
@WithMockUser(roles = "USER")
public void loginWithRoleUserThenExpectUserSpecificContent() throws Exception {
    mockMvc.perform(get("/index"))
            .andExpect(status().isOk())
            .andExpect(content().string(containsString("This content is only shown to users.")));
}

更多的例子在github上

其他回答

阅读这些答案,我可以看到很多与Spring版本4有关的内容。x,由于各种原因,我使用3.2.0版本。因此,直接从content()中获得json支持是不可能的。

我发现使用MockMvcResultMatchers。jsonPath非常简单,而且非常好用。下面是一个测试post方法的例子。

这个解决方案的好处是,您仍然在匹配属性,而不是依赖于完整的json字符串比较。

(使用org.springframework.test.web.servlet.result.MockMvcResultMatchers)

String expectedData = "some value";
mockMvc.perform(post("/endPoint")
                .contentType(MediaType.APPLICATION_JSON)
                .content(mockRequestBodyAsString.getBytes()))
                .andExpect(status().isOk())
                .andExpect(MockMvcResultMatchers.jsonPath("$.data").value(expectedData));

请求体只是一个json字符串,如果你想的话,你可以很容易地从一个真实的json模拟数据文件中加载它,但我没有在这里包括它,因为它会偏离问题。

实际返回的json应该是这样的:

{
    "data":"some value"
}

另一个例子是:

.andExpect (jsonPath(“$”)。value(containsString("你已成功删除")));

身体反应:

Body =成功删除ID为1的[Object]

String body = mockMvc.perform(bla... bla).andReturn().getResolvedException().getMessage()

这将为您提供响应的主体。“用户名已被占用”在你的情况下。

Spring MockMvc现在直接支持JSON。所以你只需说:

.andExpect(content().json("{'message':'ok'}"));

与字符串比较不同,它会说“缺少字段xyz”或“消息预期'ok'得到'nok'”之类的东西。

该方法是在Spring 4.1中引入的。

您可以使用getContentAsString方法以字符串形式获取响应数据。

    String payload = "....";
    String apiToTest = "....";
    
    MvcResult mvcResult = mockMvc.
                perform(post(apiToTest).
                content(payload).
                contentType(MediaType.APPLICATION_JSON)).
                andReturn();
    
    String responseData = mvcResult.getResponse().getContentAsString();

您可以参考此链接进行测试应用。