Spring Boot JUnit5单元测试:Service层返回Null但HTTP状态码为2XX
JUnit5测试Spring Boot服务时返回体为Null但状态码2XX的解决方法
核心问题是未正确Mock Service依赖的Repository层方法,且部分测试的Stub顺序错误,导致Service执行时无法获取预期数据,最终返回体为Null。以下是具体问题分析和修正方案:
问题拆解
- 错误Mock了Service自身方法:在
findAll测试中,你Stub的是garbageTypeService.findAll(),但Service的findAll实际依赖garbageTypeRepository.findAll(),应该Mock Repository的方法而非Service自己的方法。 - Stub顺序颠倒:
findAll测试中先调用了Service方法,之后才设置Mock返回值,此时方法已执行完毕,Stub不会生效。必须先Stub Repository方法,再调用Service方法。 - 未Stub其他Repository操作:
getGarbage_typeById和createGarbage_type测试中,没有Mock对应的repository.findById()和repository.save()方法,导致Service无法获取数据,返回体为Null。
修正后的完整测试代码
@ExtendWith(MockitoExtension.class) class GarbageTypeServiceTest { @InjectMocks private GarbageTypeService garbageTypeService; @Mock private GarbageTypeRepository garbageTypeRepository; Garbage_type g1 = new Garbage_type(0, "寶特瓶", 0.012); Garbage_type g2 = new Garbage_type(1, "鐵鋁罐", 0.2); Garbage_type g3 = new Garbage_type(2, "紙類", 0.003); Garbage_type g4 = new Garbage_type(3, "鋁箔包", 0.5); @Test void getGarbage_typeById() throws JsonProcessingException { // Mock Repository的findById方法,返回预期数据 Mockito.when(garbageTypeRepository.findById(0L)).thenReturn(Optional.of(g1)); ResponseEntity<Garbage_type> _ResGarbageType = garbageTypeService.getGarbage_typeById(0); Garbage_type _garbageType = _ResGarbageType.getBody(); String jsonInput = this.convertToJson(g1); String jsonOutput = this.convertToJson(_garbageType); System.out.println("Status Code :" + _ResGarbageType.getStatusCode()); System.out.println("Input:" + jsonInput); System.out.println("Output:" + jsonOutput); assertThat(jsonInput).isEqualTo(jsonOutput); } @Test void createGarbage_type() throws JsonProcessingException { Garbage_type g5 = new Garbage_type(4, "廚餘", 0.15); // Mock Repository的save方法,返回传入的对象 Mockito.when(garbageTypeRepository.save(Mockito.any(Garbage_type.class))).thenReturn(g5); ResponseEntity<Garbage_type> _ResGarbageType = garbageTypeService.createGarbage_type(g5); Garbage_type _garbageType = _ResGarbageType.getBody(); String jsonInput = this.convertToJson(g5); String jsonOutput = this.convertToJson(_garbageType); System.out.println("Status Code :" + _ResGarbageType.getStatusCode()); System.out.println("Input:" + jsonInput); System.out.println("Output:" + jsonOutput); assertThat(jsonInput).isEqualTo(jsonOutput); } @Test void findAll() throws JsonProcessingException { List<Garbage_type> _garbageTypeList = Arrays.asList(g1, g2, g3, g4); // 先Mock Repository的findAll方法,返回预期列表 Mockito.when(garbageTypeRepository.findAll()).thenReturn(_garbageTypeList); // 再调用Service方法 List<Garbage_type> _ResGarbageType = garbageTypeService.findAll(); String jsonInput = this.convertToJson(_ResGarbageType); String jsonOutput = this.convertToJson(_garbageTypeList); System.out.println("Input:" + jsonInput); System.out.println("Output:" + jsonOutput); assertThat(jsonInput).isEqualTo(jsonOutput); } @Test void findByGarbageTypeId() { // 同理,需Mock对应的Repository方法 } private String convertToJson(Object obj) throws JsonProcessingException { ObjectMapper objectMapper = new ObjectMapper(); return objectMapper.writeValueAsString(obj); } }
额外注意事项
- 检查
GarbageTypeService的实现逻辑:比如getGarbage_typeById是否正确处理了repository.findById返回的Optional,若Optional为空时是否仍返回2XX状态码但体为Null,这可能是状态码正常但返回体Null的另一个原因。 - 若JSON字符串比较失败,建议给
Garbage_type类实现equals和hashCode,或配置ObjectMapper忽略字段顺序,避免因序列化顺序差异导致断言失败。
内容的提问来源于stack exchange,提问作者FKT
相关产品推荐
相关产品推荐

