如何使用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
相关产品推荐
相关产品推荐

