如何使用mockMvc检查响应正文中的string
我有简单的集成testing
@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(?); }
在最后一行,我想比较收到的响应正文string和预期的string
作为回应,我得到:
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
尝试了一些与内容(),身体()的技巧,但没有任何工作。
您可以调用andReturn()
并使用返回的MvcResult
对象以String
获取内容。 见下文
MvcResult result = 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()) .andReturn(); String content = result.getResponse().getContentAsString(); // do what you will
@Sotirios Delimanolis答案做的工作,但我正在寻找比较这个mockMvc断言中的string
所以在这里
.andExpect(content().string("\"Username already taken - please try with different username\""));
当然,我的断言失败了:
java.lang.AssertionError: Response content expected: <"Username already taken - please try with different username"> but was:<"Something gone wrong">
因为:
MockHttpServletResponse: Body = "Something gone wrong"
所以这certificate了它的工作原理!
Spring MockMvc现在直接支持JSON。 所以你只是说:
.andExpect(content().json("{'message':'ok'}"));
而不像string比较,它会说类似“缺less领域xyz”或“消息预期”确定“得到”nok“。
这个方法在Spring 4.1中引入。
阅读这些答案,我可以看到很多与Spring 4.x版本相关的内容,由于各种原因我正在使用3.2.0版本。 所以像json支持直接从content()
是不可能的。
我发现使用MockMvcResultMatchers.jsonPath
是非常容易的,而且是一种享受。 这里是一个testingpost方法的例子。
这个解决scheme的好处是,你仍然在匹配的属性,而不是依靠完整的JSONstring比较。
(使用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));
请求体只是一个JSONstring,如果你想,你可以很容易地从一个真正的JSON模拟数据文件加载,但我没有包括在这里,因为它会偏离问题。
实际返回的json看起来像这样:
{ "data":"some value" }
String body = mockMvc.perform(bla... bla).andReturn().getResolvedException().getMessage()
这应该给你的回应的身体。 “您的用户名已被占用”。
Spring Security的@WithMockUser
和hamcrest的containsString
匹配器为一个简单而优雅的解决scheme:
@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的例子