You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot单元测试无论断言内容如何始终通过的问题排查

Spring Boot MockMvc测试在mvn clean package中未触发断言失败的问题

问题描述

部署Spring Boot项目时,DevOps执行mvn clean package步骤,测试输出始终显示:

Tests run: 2, Failures: 0, Errors: 0, Skipped: 0

即使在第二个测试方法中故意使用接口实际不会返回的"fal"作为message的断言值,测试依然通过,未触发预期的失败。

测试代码

@SpringBootTest(classes = {DemoApplication.class}, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureMockMvc
public class MockMvcTestor {
    @Autowired
    private MockMvc mockMvc;

    @MockBean
    private FriendshipService friendshipService;

    @MockBean
    private UserService userService;

    @Test
    @DisplayName("测试 POST 创建好友关系接口")
    public void testFriendController_ValidUserId() throws Exception {
        // 模拟 userService 的行为
        when(userService.getUser(1)).thenReturn(new User()); // 返回一个有效用户
        when(userService.getUser(2)).thenReturn(new User()); // 返回一个有效用户
        when(friendshipService.getFriendshipByTwoUserId(1, 2)).thenReturn(null); // 模拟没有好友关系

        // 执行 POST 请求
        mockMvc.perform(MockMvcRequestBuilders.post("/friendship/BuildRelations")
                        .contentType(MediaType.APPLICATION_FORM_URLENCODED)
                        .param("userId1", "1")
                        .param("userId2", "2"))
                .andExpect(status().isOk())
                .andDo(MockMvcResultHandlers.print())
                .andExpect(MockMvcResultMatchers.jsonPath("$.code").value(0)) // 验证返回的 code
                .andExpect(MockMvcResultMatchers.jsonPath("$.message").value("Susad")) // 验证返回的 message
                .andReturn();
    }

    @Test
    @DisplayName("测试 POST 创建用户接口")
    public void testAddUser_ValidUser() throws Exception {
        // 创建 UserDTO 对象
        UserDTO userDTO = new UserDTO();
        userDTO.setUsername("testuser");
        userDTO.setPassword("password");
        userDTO.setGender("Male");
        userDTO.setEmail("test@example.com");
        userDTO.setStatus("Active");

        // 模拟 userService.addUser() 方法,不返回任何值
        doNothing().when(userService).addUser(Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.any(byte[].class));

        // 创建一个模拟的文件
        MockMultipartFile avatarFile = new MockMultipartFile("avatorPic", "avatar.jpg", MediaType.IMAGE_JPEG_VALUE, "dummy data".getBytes());

        // 发送 POST 请求
        mockMvc.perform(MockMvcRequestBuilders.multipart("/users/addUser")
                        .file(avatarFile)
                        .param("username", userDTO.getUsername())
                        .param("password", userDTO.getPassword())
                        .param("gender", userDTO.getGender())
                        .param("email", userDTO.getEmail())
                        .param("status", userDTO.getStatus()))
                .andExpect(status().isOk())
                .andDo(MockMvcResultHandlers.print())
                .andExpect(MockMvcResultMatchers.jsonPath("$.code").value(0))
                .andExpect(MockMvcResultMatchers.jsonPath("$.message").value("fal"));
    }
}

可能的原因及解决方法

1. Maven构建忽略了测试失败

DevOps工作流中的mvn命令可能添加了-Dmaven.test.failure.ignore=true参数,该参数会强制Maven忽略测试失败,继续执行构建,导致测试报告显示无失败。

  • 排查:查看DevOps配置文件(如GitHub Actions YAML、Jenkinsfile)中的mvn命令参数。
  • 解决:移除该参数,让Maven在测试失败时终止构建。

2. JSONPath断言未正确匹配

如果控制器返回的JSON中不存在$.message字段,或字段类型与断言值不匹配,部分Spring版本可能不会触发断言失败。

  • 排查:本地运行测试,通过andDo(MockMvcResultHandlers.print())查看实际响应的JSON结构。
  • 解决:添加字段存在性检查,完善断言:
    .andExpect(MockMvcResultMatchers.jsonPath("$.message").exists())
    .andExpect(MockMvcResultMatchers.jsonPath("$.message").value("fal"))
    

3. MockBean配置导致控制器逻辑偏离预期

测试中Mock的Service返回空对象(如new User()),如果控制器需要对象的具体属性才能生成预期响应,会导致返回结果与断言不匹配,但由于Mock逻辑未覆盖控制器的分支判断,可能让断言看似"通过"。

  • 解决:完善Mock对象的属性,确保符合控制器逻辑要求:
    User user1 = new User();
    user1.setId(1);
    when(userService.getUser(1)).thenReturn(user1);
    

4. 测试依赖版本不兼容

JUnit与Spring Test版本不兼容(如JUnit 4和JUnit 5混用),或Spring Boot版本与测试依赖不匹配,可能导致断言失效。

  • 排查:检查pom.xml中的spring-boot-starter-test依赖,确保版本与Spring Boot一致,避免同时引入JUnit 4和JUnit 5依赖。

内容的提问来源于stack exchange,提问作者姚 Haihan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 20:22:09