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

Spring 6.1升级后请求参数校验测试失败问题求助

解决方案

问题根源

Spring Boot 3.2.x(基于Spring Framework 6.1+)引入了HandlerMethodValidationException专门处理方法参数验证错误,且默认不再自动将该异常转换为400 Bad Request响应,而是直接抛出异常,导致原有测试中预期400状态的断言失效。

最快优雅的解决方法(二选一即可)

方法1:调整测试代码,直接验证异常(无需修改业务代码)

利用Spring MVC Test提供的匹配器,直接断言验证异常的存在及细节,替代原有对响应内容的硬编码断言:

mvc.perform(get(ENDPOINT)
        .queryParam("myparam", "100"))
    .andExpect(status().isBadRequest())
    .andExpect(handler().handlerMethodValidationError())
    .andExpect(result -> {
        HandlerMethodValidationException ex = (HandlerMethodValidationException) result.getResolvedException();
        // 验证具体的错误字段和提示信息
        assertThat(ex.getAllValidationResults()).hasSize(1);
        var fieldError = ex.getAllValidationResults().get(0).getFieldErrors().get(0);
        assertThat(fieldError.getField()).isEqualTo("myparam");
        assertThat(fieldError.getDefaultMessage()).isEqualTo("size must be between 0 and 10");
    });

方法2:在测试中临时添加异常处理器(保留原有测试断言)

如果希望完全复用原有测试的响应断言,可在构建MockMvc时添加临时的异常处理器,将HandlerMethodValidationException转换为预期的400响应:

// 构建MockMvc时添加异常处理逻辑
mvc = MockMvcBuilders.webAppContextSetup(webApplicationContext)
        .setHandlerExceptionResolvers((request, response, handler, ex) -> {
            if (ex instanceof HandlerMethodValidationException) {
                response.setStatus(HttpStatus.BAD_REQUEST.value());
                response.setContentType(APPLICATION_PROBLEM_JSON_VALUE);
                // 写入原有测试预期的JSON内容
                try (PrintWriter writer = response.getWriter()) {
                    writer.write("""
                        {
                          "type": "/problems/validation-error",
                          "title": "The request parameters didn't validate",
                          "instance": "my-endpoint",
                          "status": 400,
                          "errors": [
                            {
                              "path":"myparam","message":"size must be between 0 and 10"
                            }
                          ]
                        }
                        """);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
                return new ModelAndView();
            }
            return null;
        })
        .build();

// 原有测试代码无需修改,可直接运行
mvc.perform(get(ENDPOINT)
        .queryParam("myparam", "100"))
    .andExpectAll(
        status().isBadRequest(),
        content().contentType(APPLICATION_PROBLEM_JSON),
        content().json("""
                    {
                      "type": "/problems/validation-error",
                      "title": "The request parameters didn't validate",
                      "instance": "my-endpoint",
                      "status": 400,
                      "errors": [
                        {
                          "path":"myparam","message":"size must be between 0 and 10"
                        }
                      ]
                    }
                    """, true));

补充说明

如果希望业务代码也恢复升级前的响应行为(即全局自动处理该异常返回400+Problem JSON),可以添加一个@ControllerAdvice类统一处理,不过这属于业务代码变更,按需选择即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 03:56:14