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

为已运行的Spring MVC应用添加JUnit测试套件的方法咨询

为传统Spring MVC应用添加Controller API测试的步骤

1. 添加必要的测试依赖

在你的构建工具(Maven/Gradle)中加入以下核心测试库,所有依赖均为Spring生态基础组件,无Spring Boot相关内容:

  • JUnit:选择JUnit 4或5(以下以JUnit 4为例,JUnit 5仅需调整注解和依赖坐标)
  • Spring Test:提供MockMvc、TestContext等Web测试核心支持
  • Mockito:用于Mock Controller依赖的Service/DAO层,隔离真实业务逻辑
  • Jackson Databind(可选):用于JSON响应的断言处理

Maven依赖示例:

<dependencies>
    <!-- JUnit 4 -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.13.2</version>
        <scope>test</scope>
    </dependency>
    <!-- Spring Test(版本需与应用Spring核心版本完全一致) -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
        <version>你的Spring版本号</version>
        <scope>test</scope>
    </dependency>
    <!-- Mockito -->
    <dependency>
        <groupId>org.mockito</groupId>
        <artifactId>mockito-core</artifactId>
        <version>4.11.0</version>
        <scope>test</scope>
    </dependency>
    <!-- JSON处理 -->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.15.2</version>
        <scope>test</scope>
    </dependency>
</dependencies>

2. 编写Controller测试类基础配置

根据测试需求选择两种配置方式:

方式一:加载完整Web上下文(适合集成测试)

使用Spring Test注解加载应用原有的Spring配置,测试真实的请求路由和上下文:

import org.junit.Before;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(locations = {
    "classpath:spring-mvc.xml", // 应用原有的MVC配置文件
    "classpath:spring-service.xml" // 可选,若需加载真实Service层
})
public class UserControllerTest {

    @Autowired
    private WebApplicationContext webApplicationContext;

    private MockMvc mockMvc;

    @Before
    public void setup() {
        // 基于Web上下文构建MockMvc
        mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
    }
}

若应用使用JavaConfig而非XML,@ContextConfiguration可直接指定配置类:

@ContextConfiguration(classes = {WebMvcConfig.class, ServiceConfig.class})

方式二:Mock依赖+独立Controller(适合单元测试)

仅加载待测试的Controller,用MockitoMock其依赖,测试速度更快:

import org.junit.Before;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;

@RunWith(MockitoJUnitRunner.class)
public class UserControllerTest {

    @Mock
    private UserService userService; // Controller依赖的Service

    @InjectMocks
    private UserController userController; // 待测试的Controller

    private MockMvc mockMvc;

    @Before
    public void setup() {
        // 基于独立Controller实例构建MockMvc
        mockMvc = MockMvcBuilders.standaloneSetup(userController).build();
    }
}

3. 编写具体API测试用例

使用MockMvc模拟HTTP请求,验证响应状态、内容、参数绑定等核心逻辑:

示例1:GET请求测试

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import static org.mockito.Mockito.when;

@Test
public void testGetUserById() throws Exception {
    // 预设Mock Service的返回值
    User mockUser = new User(1L, "testUser");
    when(userService.getUserById(1L)).thenReturn(mockUser);

    // 模拟GET请求并断言响应
    mockMvc.perform(get("/users/{id}", 1L)
            .contentType("application/json"))
            .andExpect(status().isOk())
            .andExpect(jsonPath("$.id").value(1L))
            .andExpect(jsonPath("$.username").value("testUser"));
}

示例2:POST请求测试

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import static org.mockito.Mockito.verify;

@Test
public void testCreateUser() throws Exception {
    User newUser = new User(null, "newUser");
    User savedUser = new User(2L, "newUser");
    when(userService.saveUser(newUser)).thenReturn(savedUser);

    // 模拟POST请求,传递JSON参数
    mockMvc.perform(post("/users")
            .contentType("application/json")
            .content("{\"username\":\"newUser\"}"))
            .andExpect(status().isCreated())
            .andExpect(jsonPath("$.id").value(2L))
            .andExpect(jsonPath("$.username").value("newUser"));

    // 验证Mock Service方法是否被正确调用
    verify(userService).saveUser(newUser);
}

示例3:参数校验失败场景测试

@Test
public void testCreateUserWithInvalidParam() throws Exception {
    // 传递空用户名,触发JSR-380校验失败
    mockMvc.perform(post("/users")
            .contentType("application/json")
            .content("{\"username\":\"\"}"))
            .andExpect(status().isBadRequest())
            .andExpect(jsonPath("$.errors[0].message").value("用户名不能为空"));
}

4. 组织测试套件

将多个Controller测试类整合为一个套件,方便批量运行:

import org.junit.runner.RunWith;
import org.junit.runners.Suite;

@RunWith(Suite.class)
@Suite.SuiteClasses({
    UserControllerTest.class,
    OrderControllerTest.class,
    // 其他Controller测试类
})
public class ControllerTestSuite {
    // 无需编写业务代码,仅作为套件入口
}

5. 关键注意事项

  • 版本一致性:Spring Test版本必须与应用Spring核心版本完全匹配,避免兼容性问题
  • 测试隔离:每个测试方法独立,使用@Before初始化、@After清理状态
  • 避免外部依赖:测试Controller时不要依赖真实数据库、外部接口,全部用Mock替代
  • 覆盖核心场景:重点测试正常流程、异常流程、参数边界、权限控制(若有)等场景

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 12:35:11