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

JUnit期望返回400响应却得200:SpringBoot接口测试问题

SpringBoot /save接口JUnit测试未触发预期400错误

问题场景

  • 测试SpringBoot控制器的/save接口,预期发送包含null agency名称的JSON请求时,返回400状态码及响应信息“Agency Name cannot be null”
  • Postman本地测试符合预期,但JUnit测试始终返回200状态码,断言失败

JUnit测试代码

@SpringBootTest
@AutoConfigureMockMvc
@WithMockUser(username = "test", password = "test", authorities = { "ANY " })
public class AgencyControllerIT {

    @Autowired
    private MockMvc mvc;

    @Mock
    private AgencyRepository mRepository;

    @MockBean
    private AgencyService mService;
        
    @Test
    public void testControllerSaveWithoutAgencyName() throws Exception {
        // Create JSON
        String body = "[{" +
                "\"agency\": null," +
                "\"type\": \"Type\"," +
                "\"defaultText\": \"DefaultText\"" +
                "}]";

        //Perform request to endpoint and assert bad request
        this.mvc.perform(MockMvcRequestBuilders.post("/myApplication/save")
                        .contentType(MediaType.APPLICATION_JSON)
                        .content(body))
                .andDo(print())
                .andExpect(status().isBadRequest())
                .andExpect(content().string("Agency Name cannot be null"))
                .andReturn();
        //Verify service is not called
        verify(mService, times(0)).merge(any());
    }
}

测试响应结果

MockHttpServletRequest:
      HTTP Method = POST
      Request URI = /myApplication/save
       Parameters = {}
          Headers = [Content-Type:"application/json;charset=UTF-8"]
             Body = [{"agency:" null, "type": "Type","defaultText": "DefaultText"}]
    Session Attrs = {}

MockHttpServletResponse:
           Status = 200
    Error message = null
          Headers = [Vary:"Origin", "Access-Control-Request-Method", "Access-Control-Request-Headers", Content-Type:"application/json", X-Content-Type-Options:"nosniff", X-XSS-Protection:"0", Cache-Control:"no-cache, no-store, max-age=0, must-revalidate", Pragma:"no-cache", Expires:"0", X-Frame-Options:"DENY"]
     Content type = application/json
             Body = [ ]
    Forwarded URL = null
   Redirected URL = null
          Cookies = []

java.lang.AssertionError: Status expected:<400> but was:<200>
Expected :400
Actual   :200

控制器代码

@Transactional
@PostMapping(value = {"/save"}, produces = {"application/json"})
public ResponseEntity<List<Agency>> save(@RequestBody List<Agency> updatedValues){
    String message = agencyService.postFieldValidation(updatedValues);
    if(message != null){
        return new ResponseEntity(message, HttpStatus.BAD_REQUEST);
    }
    List<Agency> result = agencyService.merge(updatedValues);
    return new ResponseEntity<>(result, HttpStatus.OK);
}

Service层校验方法

public String postFieldValidation(List<Agency> updatedValues) {
    String message = null;
    for (Agency updatedValue : updatedValues) {
        if (updatedValue.getAgency() == null)
            message = "Agency name cannot be null";
        else if (updatedValue.getDefaultText() == null)
            message = "Default Text cannot be null";
    }
    return message;
}

调试排查结果

  • 控制器中的updatedValues参数能正常接收请求内容
  • 但调用Service层的postFieldValidation方法时,传入的参数为null,导致校验逻辑被跳过,最终接口返回200状态码

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 19:31:04