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

SpringBoot API测试返回空JSON,Postman请求正常问题求助

SpringBoot API测试问题:MockMvc请求返回空JSON,Postman正常

问题现象

测试类中执行GET请求/employee/1时,MockHttpServletResponse的Body为空,抛出断言错误java.lang.AssertionError: No value at JSON path "$.firstName";但用Postman执行相同请求能正常获取正确结果。

相关日志

MockHttpServletRequest:
      HTTP Method = GET
      Request URI = /employee/1
       Parameters = {}
          Headers = []
             Body = null
    Session Attrs = {}
    
Handler:
             Type = com.openclassrooms.api.controller.EmployeeController
           Method = com.openclassrooms.api.controller.EmployeeController#getEmployee(Long)

Async:
    Async started = false
     Async result = null

Resolved Exception:
             Type = null

ModelAndView:
        View name = null
             View = null
            Model = null

FlashMap:
       Attributes = null

MockHttpServletResponse:
           Status = 200
    Error message = null
          Headers = []
     Content type = null
             Body = 
    Forwarded URL = null
   Redirected URL = null
          Cookies = []

问题原因

测试类中使用@MockBean注解创建了EmployeeService的Mock实例,但没有为该Mock对象的getEmployee方法设置模拟返回值。当Controller调用employeeService.getEmployee(1L)时,Mock对象默认返回Optional.empty(),导致Controller返回的响应Body为空,最终断言失败。而Postman运行时使用的是真实的EmployeeService实例,会连接数据库查询真实数据,所以能正常返回结果。

解决方案

使用Mockito为Mock的EmployeeService设置方法调用的返回值,模拟存在目标Employee的场景。

修改后的测试类代码

package com.openclassrooms.api;

import static org.hamcrest.CoreMatchers.is;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import java.util.Optional;

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.openclassrooms.api.controller.EmployeeController;
import com.openclassrooms.api.models.Employee;
import com.openclassrooms.api.service.EmployeeService;

@WebMvcTest(controllers = EmployeeController.class)
public class EmployeeControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @MockBean
    private EmployeeService employeeService;

    @Test
    public void testGetEmployeeById() throws Exception {
        // 模拟测试数据
        Employee mockEmployee = new Employee();
        mockEmployee.setId(1L);
        mockEmployee.setFirstName("Laurent");
        mockEmployee.setLastName("Dupont");
        mockEmployee.setMail("laurent.dupont@mail.com");
        mockEmployee.setPassword("password123");

        // 为Mock的Service设置返回值
        when(employeeService.getEmployee(1L)).thenReturn(Optional.of(mockEmployee));

        mockMvc.perform(get("/employee/1")
                        .contentType(MediaType.APPLICATION_JSON))
                .andExpect(status().isOk())
                .andDo(print())
                .andExpect(jsonPath("$.firstName", is("Laurent")));
    }
}

额外优化建议

  • 规范测试方法命名:原测试方法名testGetEmployees与测试单个员工的逻辑不符,改为testGetEmployeeById更清晰。
  • 指定请求MediaType:在perform中添加.contentType(MediaType.APPLICATION_JSON),让请求更符合REST API规范。
  • 避免返回null:Controller中的getEmployee(Long id)方法,当emp为空时不要返回null,直接返回emp(即Optional.empty()),避免返回null引发的序列化问题或空指针风险:
@GetMapping("/employee/{id}")
public Optional<Employee> getEmployee(@PathVariable("id") final Long id) {
    Optional<Employee> emp = employeeService.getEmployee(id);
    if (emp.isPresent()) {
        System.out.println(emp.get().getFirstName());
    } else {
        System.out.println("ABSENT");
    }
    return emp;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 19:20:47