ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

SpringBoot接口测试:MockMvc实战GET/POST请求

SpringBoot接口测试:MockMvc实战GET/POST请求 1. 项目概述在SpringBoot项目开发中接口测试是保证代码质量的重要环节。MockMvc作为Spring Test模块的核心组件能够在不启动完整Web容器的情况下对Controller层进行高效测试。本文将深入讲解如何利用MockMvc测试GET和POST接口覆盖单参数、多参数等典型场景。2. 环境准备与基础配置2.1 依赖引入首先确保项目中已包含必要的测试依赖dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-test/artifactId scopetest/scope /dependency2.2 测试类基础结构创建测试类时需要添加以下注解SpringBootTest AutoConfigureMockMvc public class ControllerTest { Autowired private MockMvc mockMvc; // 测试方法将在这里编写 }注意AutoConfigureMockMvc注解会自动配置MockMvc实例避免了手动创建的繁琐过程。3. GET请求测试实战3.1 单参数GET请求测试假设有一个查询用户信息的接口GetMapping(/user) public User getUser(RequestParam String userId) { // 业务逻辑 }对应的测试方法Test public void testGetUserWithSingleParam() throws Exception { mockMvc.perform(get(/user) .param(userId, 123)) .andExpect(status().isOk()) .andExpect(jsonPath($.username).value(testUser)); }关键点解析perform()方法发起请求param()设置请求参数andExpect()验证响应状态和内容3.2 多参数GET请求测试对于多参数接口GetMapping(/search) public ListUser searchUsers( RequestParam String keyword, RequestParam int page, RequestParam int size) { // 业务逻辑 }测试方法示例Test public void testSearchWithMultipleParams() throws Exception { mockMvc.perform(get(/search) .param(keyword, spring) .param(page, 1) .param(size, 10)) .andExpect(status().isOk()) .andExpect(jsonPath($.length()).value(10)); }4. POST请求测试详解4.1 表单格式POST请求测试表单提交接口PostMapping(/login) public ResponseEntity login( RequestParam String username, RequestParam String password) { // 认证逻辑 }测试代码Test public void testFormPost() throws Exception { mockMvc.perform(post(/login) .param(username, admin) .param(password, 123456) .contentType(MediaType.APPLICATION_FORM_URLENCODED)) .andExpect(status().isOk()); }4.2 JSON格式POST请求对于接收JSON的接口PostMapping(/create) public User createUser(RequestBody UserDTO userDTO) { // 创建逻辑 }测试方法Test public void testJsonPost() throws Exception { String userJson {\username\:\newUser\,\email\:\testexample.com\}; mockMvc.perform(post(/create) .content(userJson) .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isCreated()) .andExpect(jsonPath($.id).exists()); }5. 高级测试技巧5.1 请求头设置某些接口需要特定的请求头Test public void testWithHeaders() throws Exception { mockMvc.perform(get(/secure) .header(Authorization, Bearer token123) .header(X-Custom-Header, value)) .andExpect(status().isOk()); }5.2 响应结果处理除了简单的状态验证还可以对响应内容进行详细断言Test public void testResponseHandling() throws Exception { MvcResult result mockMvc.perform(get(/data)) .andExpect(status().isOk()) .andReturn(); String content result.getResponse().getContentAsString(); // 对content进行更复杂的断言 }6. 常见问题与解决方案6.1 中文参数乱码问题解决方案是在测试配置中添加字符编码设置Test public void testChineseParam() throws Exception { mockMvc.perform(get(/search) .param(keyword, 中文) .characterEncoding(UTF-8)) .andExpect(status().isOk()); }6.2 文件上传测试测试文件上传接口Test public void testFileUpload() throws Exception { MockMultipartFile file new MockMultipartFile( file, test.txt, text/plain, file content.getBytes()); mockMvc.perform(multipart(/upload) .file(file)) .andExpect(status().isOk()); }6.3 会话和Cookie处理需要会话支持的测试Test public void testWithSession() throws Exception { MockHttpSession session new MockHttpSession(); session.setAttribute(key, value); mockMvc.perform(get(/session) .session(session)) .andExpect(status().isOk()); }7. 测试最佳实践测试隔离每个测试方法应该是独立的不依赖其他测试的执行顺序清晰的断言每个测试应该只验证一个明确的业务点合理的命名测试方法名应该清晰表达测试意图适当的Mock对于依赖的服务合理使用Mockito等工具进行模拟提示对于复杂的业务场景建议将测试数据准备和测试逻辑分离提高测试代码的可维护性。在实际项目中我发现合理组织测试代码的结构非常重要。通常我会按照以下方式组织基础测试数据放在Before方法中公共的请求构建逻辑提取为私有方法复杂的断言逻辑封装为自定义的匹配器MockMvc测试虽然强大但也需要注意不要过度测试。应该把重点放在验证Controller层的输入输出转换、参数绑定等Web层特有的逻辑上业务逻辑的详细测试应该放在Service层的单元测试中。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进