使用MockMvc检查响应体中的字符串
技术背景
在Java开发中,使用Spring框架进行Web应用开发时,MockMvc是一个强大的工具,用于对控制器进行单元测试。在测试过程中,我们经常需要检查响应体中的字符串是否符合预期,以确保接口的正确性。
实现步骤
方法一:使用 andReturn()
获取响应内容
- 执行请求并获取
MvcResult
对象。 - 从
MvcResult
对象中获取响应内容。 - 对响应内容进行断言。
1 2 3 4 5 6 7 8
| MvcResult result = mockMvc.perform(post("/api/users").header("Authorization", base64ForTestUser).contentType(MediaType.APPLICATION_JSON) .content("{\"userName\":\"testUserDetails\",\"firstName\":\"xxx\",\"lastName\":\"xxx\",\"password\":\"xxx\"}")) .andDo(MockMvcResultHandlers.print()) .andExpect(status().isBadRequest()) .andReturn();
String content = result.getResponse().getContentAsString();
|
方法二:使用 content().string()
进行字符串比较
直接在 andExpect()
中使用 content().string()
方法进行字符串比较。
1
| .andExpect(content().string("\"Username already taken - please try with different username\""));
|
方法三:使用 content().json()
进行JSON比较
Spring MockMvc从4.1版本开始支持直接进行JSON比较。
1
| .andExpect(content().json("{'message':'ok'}"));
|
方法四:使用 jsonPath
进行JSON属性匹配
对于JSON响应,可以使用 jsonPath
来匹配特定的属性值。
1 2 3 4 5 6
| String expectedData = "some value"; mockMvc.perform(post("/endPoint") .contentType(MediaType.APPLICATION_JSON) .content(mockRequestBodyAsString.getBytes())) .andExpect(status().isOk()) .andExpect(MockMvcResultMatchers.jsonPath("$.data").value(expectedData));
|
核心代码
以下是一个完整的示例,展示了如何使用 MockMvc
检查响应体中的字符串:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@WebMvcTest public class UserControllerTest {
@Autowired private MockMvc mockMvc;
@Test public void shouldReturnErrorMessageToAdminWhenCreatingUserWithUsedUserName() throws Exception { mockMvc.perform(MockMvcRequestBuilders.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(MockMvcResultMatchers.content().string("\"Username already taken\"")); } }
|
最佳实践
- 对于简单的字符串响应,使用
content().string()
方法进行比较。 - 对于JSON响应,优先使用
content().json()
或 jsonPath
进行比较,这样可以更灵活地处理JSON结构。 - 如果响应内容较大,可以将预期的JSON内容存储在文件中,然后读取文件内容进行比较。
常见问题
- JSON格式问题:在使用
content().json()
进行比较时,要确保JSON格式正确,否则会导致比较失败。 - 字符串引号问题:在使用
content().string()
进行比较时,要注意字符串中的引号是否匹配。 - 版本兼容性问题:
content().json()
方法是从Spring 4.1版本开始支持的,如果使用的是旧版本,可能无法使用该方法。