Spring中测试返回ResponseEntity的Service层POST方法问题
嗨,我来帮你把这个测试方法搞定!你已经有了不错的开头,接下来咱们分两种常见场景来完善——一种是单元测试服务类本身,另一种是测试调用该服务的控制器接口,你可以根据自己的需求选择:
场景1:单元测试服务类(Service Layer Unit Test)
如果你的目标是直接验证addCustomer服务方法的逻辑,咱们可以这样写:
首先要确保测试类里已经Mock了服务依赖的Repository,然后通过Mockito stubbing模拟Repository的行为,最后断言返回的ResponseEntity是否符合预期:
import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.*; @ExtendWith(MockitoExtension.class) class CustomerServiceTest { @Mock private CustomerRepository customerRepository; // 替换成你实际的Repository类型 @InjectMocks private CustomerService customerService; // 你的目标服务类 @Test void addCustomer_ShouldReturnOkResponseWithSavedCustomer() throws Exception { // 1. 准备测试数据 String testName = "Test Name"; String testEmail = "test@email.com"; Customer inputCustomer = new Customer(testName, testEmail); // 模拟Repository保存后返回的带ID的对象(根据你的实体类构造方法调整) Customer savedCustomer = new Customer(1L, testName, testEmail); // 2. Stub Repository的save方法:当传入inputCustomer时,返回模拟的savedCustomer when(customerRepository.save(inputCustomer)).thenReturn(savedCustomer); // 3. 调用目标服务方法 ResponseEntity<Customer> response = customerService.addCustomer(inputCustomer); // 4. 断言结果是否符合预期 assertEquals(HttpStatus.OK, response.getStatusCode()); assertNotNull(response.getBody()); assertEquals(savedCustomer.getId(), response.getBody().getId()); assertEquals(testName, response.getBody().getName()); assertEquals(testEmail, response.getBody().getEmail()); // 验证Repository的save方法确实被调用了一次 verify(customerRepository, times(1)).save(inputCustomer); } }
场景2:集成测试控制器接口(Controller Integration Test)
如果你是想测试暴露的POST接口(比如/api/customers),需要用MockMvc模拟HTTP请求,同时Mock服务类的行为:
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; import static org.mockito.Mockito.*; @WebMvcTest(CustomerController.class) // 仅加载控制器相关的Spring Bean class CustomerControllerTest { @Autowired private MockMvc mockMvc; @MockBean private CustomerService customerService; // Mock服务类 @Test void addCustomer_ShouldReturnOkWithCustomerJson() throws Exception { // 1. 准备测试数据 String testName = "Test Name"; String testEmail = "test@email.com"; Customer savedCustomer = new Customer(1L, testName, testEmail); ResponseEntity<Customer> mockServiceResponse = new ResponseEntity<>(savedCustomer, HttpStatus.OK); // 2. Stub服务类的addCustomer方法:传入任意Customer时返回模拟的响应 when(customerService.addCustomer(any(Customer.class))).thenReturn(mockServiceResponse); // 3. 构造请求JSON(推荐用ObjectMapper序列化,避免手动拼接出错) ObjectMapper objectMapper = new ObjectMapper(); Customer inputCustomer = new Customer(testName, testEmail); String jsonRequest = objectMapper.writeValueAsString(inputCustomer); // 4. 模拟POST请求并断言响应结果 mockMvc.perform(post("/api/customers") // 替换成你实际的接口路径 .contentType(MediaType.APPLICATION_JSON) .content(jsonRequest)) .andExpect(status().isOk()) .andExpect(jsonPath("$.id").value(1L)) .andExpect(jsonPath("$.name").value(testName)) .andExpect(jsonPath("$.email").value(testEmail)); // 验证服务类的addCustomer方法被调用了一次 verify(customerService, times(1)).addCustomer(any(Customer.class)); } }
小提醒:
- 如果用的是JUnit 4,把
@ExtendWith(MockitoExtension.class)换成@RunWith(MockitoJUnitRunner.class)即可。 - 手动拼接JSON容易出错,用
ObjectMapper序列化实体类生成请求体更可靠。
内容的提问来源于stack exchange,提问作者GoRobotFlame
相关产品推荐
相关产品推荐

