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

如何使用Mock对象编写REST控制器POST方法的测试用例?

如何用Mock对象测试你的Spring REST POST接口

别担心,我来一步步带你搞定这个测试!我们会用Spring Boot官方推荐的测试工具组合:@WebMvcTest(专注测试控制器层)和Mockito(创建Mock对象),这样不用启动整个应用就能完成测试。

第一步:确保测试依赖到位

首先,你的项目里应该已经有spring-boot-starter-test依赖了(Spring Boot初始化项目时默认会加),如果没有的话,在pom.xml(Maven)或者build.gradle(Gradle)里加上它就行。

第二步:编写测试类结构

我们先创建对应的测试类,核心是用注解隔离控制器层,替换真实服务为Mock对象:

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 static org.mockito.Mockito.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

// 只加载目标控制器,避免启动整个应用上下文
@WebMvcTest(PersonController.class)
public class PersonControllerTest {

    // 模拟HTTP请求的核心工具
    @Autowired
    private MockMvc mockMvc;

    // 用Mock对象替换容器中的真实PersonService,隔离业务层依赖
    @MockBean
    private PersonService personService;

    // 用来把Java对象序列化为JSON请求体
    @Autowired
    private ObjectMapper objectMapper;
}

第三步:测试成功创建的正常场景

先写正常流程的测试:当服务层方法正常执行时,接口应返回200 OK并返回传入的PersonDto数据。

@Test
void createPerson_ShouldReturnOk_WhenValidRequest() throws Exception {
    // 1. 准备测试用的PersonDto对象
    PersonDto testPerson = new PersonDto();
    testPerson.setId(1L);
    testPerson.setName("John Doe");
    testPerson.setEmail("john@example.com");

    // 2. 配置Mock对象行为:调用createPerson时无需返回值(根据你的业务逻辑调整)
    doNothing().when(personService).createPerson(testPerson);

    // 3. 发送POST请求并验证响应
    mockMvc.perform(post("/persons")
                    .contentType(MediaType.APPLICATION_JSON)
                    .content(objectMapper.writeValueAsString(testPerson)))
            .andExpect(status().isOk())
            .andExpect(jsonPath("$.id").value(testPerson.getId()))
            .andExpect(jsonPath("$.name").value(testPerson.getName()))
            .andExpect(jsonPath("$.email").value(testPerson.getEmail()));

    // 4. 验证Mock方法确实被调用了一次
    verify(personService, times(1)).createPerson(testPerson);
}

第四步:测试异常场景

再测试服务层抛出异常时,接口应返回400 Bad Request的情况:

@Test
void createPerson_ShouldReturnBadRequest_WhenServiceThrowsException() throws Exception {
    // 1. 准备不符合业务规则的测试数据
    PersonDto invalidPerson = new PersonDto();
    invalidPerson.setEmail("invalid-email"); // 假设这会触发业务异常

    // 2. 配置Mock对象行为:调用createPerson时抛出指定异常
    doThrow(new IllegalArgumentException("Invalid email format")).when(personService).createPerson(invalidPerson);

    // 3. 发送请求并验证响应状态
    mockMvc.perform(post("/persons")
                    .contentType(MediaType.APPLICATION_JSON)
                    .content(objectMapper.writeValueAsString(invalidPerson)))
            .andExpect(status().isBadRequest());

    // 4. 验证Mock方法被调用
    verify(personService, times(1)).createPerson(invalidPerson);
}

关键知识点说明

  • @WebMvcTest:只加载Web层相关Bean(控制器、转换器等),测试启动速度快,避免不必要的依赖加载。
  • @MockBean:Spring自动将Mock对象注入到控制器中,确保控制器调用的是模拟服务,而非真实业务逻辑,彻底隔离测试环境。
  • MockMvc:无需启动真实服务器,直接模拟HTTP请求,验证接口的请求处理和响应是否符合预期。

这样写出来的测试既高效又可靠,完全专注于验证控制器的逻辑正确性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:03:05