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

SpringBoot无Service类时如何用JUnit、Mockito编写Controller测试用例

SpringBoot Controller单元测试实操(无Service层场景)

前置准备

首先确保你的pom.xml(Maven)或build.gradle(Gradle)中已引入SpringBoot测试启动器,里面内置了JUnit、Mockito、MockMvc等所需工具:

<!-- Maven 依赖示例 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>

你提供的UserRepository代码已经符合JPA规范,我们默认你已经有对应的User实体类,以及直接依赖UserRepository的UserController,先给出参考的Controller示例方便对照:

package com.example.spring;

import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
import java.util.Optional;

@RestController
@RequestMapping("/users")
public class UserController {
    @Resource
    private UserRepository userRepository;

    // 查询所有用户
    @GetMapping
    public List<User> getAllUsers() {
        return userRepository.findAll();
    }

    // 根据ID查询单个用户
    @GetMapping("/{id}")
    public User getUserById(@PathVariable Integer id) {
        return userRepository.findById(id).orElse(null);
    }

    // 新增用户
    @PostMapping
    public User addUser(@RequestBody User user) {
        return userRepository.save(user);
    }
}

编写Controller测试用例

我们使用@WebMvcTest注解做Controller切片测试,该注解只会加载Controller层相关Bean,不会启动完整的Spring上下文,速度更快。依赖的Repository我们用Mockito模拟,不需要真实连接数据库。
完整测试代码如下:

package com.example.spring;

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.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Arrays;
import java.util.Optional;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

// 指定要测试的Controller类
@WebMvcTest(UserController.class)
public class UserControllerTest {
    // 注入MockMvc,用于模拟发送HTTP请求
    @Autowired
    private MockMvc mockMvc;

    // 模拟UserRepository,替代真实的Bean注入到Controller中
    @MockBean
    private UserRepository userRepository;

    // JSON转换工具,用于把对象转成请求的JSON字符串
    @Autowired
    private ObjectMapper objectMapper;

    // 测试查询所有用户接口
    @Test
    public void testGetAllUsers() throws Exception {
        // 1. 模拟Repository的返回数据
        User user1 = new User(1, "张三", 20);
        User user2 = new User(2, "李四", 22);
        when(userRepository.findAll()).thenReturn(Arrays.asList(user1, user2));

        // 2. 发送GET请求到/users接口,校验响应结果
        mockMvc.perform(get("/users")
                        .contentType(MediaType.APPLICATION_JSON))
                .andExpect(status().isOk()) // 校验状态码200
                .andExpect(jsonPath("$[0].name").value("张三")) // 校验第一个用户的name字段
                .andExpect(jsonPath("$[1].age").value(22)); // 校验第二个用户的age字段
    }

    // 测试根据ID查询用户接口
    @Test
    public void testGetUserById() throws Exception {
        User mockUser = new User(1, "张三", 20);
        when(userRepository.findById(1)).thenReturn(Optional.of(mockUser));

        mockMvc.perform(get("/users/1")
                        .contentType(MediaType.APPLICATION_JSON))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.name").value("张三"));
    }

    // 测试新增用户接口
    @Test
    public void testAddUser() throws Exception {
        User newUser = new User(null, "王五", 25);
        User savedUser = new User(3, "王五", 25);
        // 模拟调用save方法时返回存好的带ID的用户
        when(userRepository.save(any(User.class))).thenReturn(savedUser);

        mockMvc.perform(post("/users")
                        .contentType(MediaType.APPLICATION_JSON)
                        // 把新增用户对象转成JSON放到请求体里
                        .content(objectMapper.writeValueAsString(newUser)))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.id").value(3))
                .andExpect(jsonPath("$.name").value("王五"));
    }
}

核心逻辑说明

  • @WebMvcTest:SpringBoot提供的切片测试注解,仅加载指定的Controller层组件,适合做Controller单元测试
  • @MockBean:将Mockito模拟的对象注入到Spring上下文中,替换掉真实的Repository实现,不需要操作真实数据库
  • MockMvc:模拟HTTP客户端,直接向Controller发送请求、接收响应,不需要启动Tomcat容器
  • when(...)thenReturn(...):Mockito的核心API,指定调用Mock对象的某个方法时要返回的模拟数据

你可以直接按照这个模板,根据你自己Controller里的接口逻辑调整模拟数据和校验规则即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 13:45:01