使用mockMVC进行Spring测试抛出ServletException

问题描述 投票:0回答:1

我有以下 Spring 测试类:


@AutoConfigureMockMvc
@Testcontainers
@ExtendWith(SpringExtension.class)
@SpringBootTest
@ActiveProfiles("test")
public class FormTest {

    @Autowired
    private MockMvc mockMvc;
    

    @Test
    public void givenInvalidForm_whenSubmitted_returns400() throws Exception {

        FormUploadDTO dto = .. generate DTO
        MvcResult mvcResult =  mockMvc.perform(post(BaseApi.BASE_API + "/forms")
                        .contentType(MediaType.APPLICATION_JSON.getMediaType())
                        .content(asJsonString(new ArrayList<>(Collections.singleton(dto)){}))
                        .andDo(print())
                        .andReturn();
        assertEquals(400, mvcResult.getResponse().getStatus());


    }

}

但是,spring-application 容器没有返回错误请求(对于

@NotNull
带注释的字段),而是抛出以下错误:

jakarta.servlet.ServletException: Request processing failed: jakarta.validation.ConstraintViolationException: submitForm.dtos[0].client: must not be null, submitForm.dtos[0].priceType: must not be null, submitForm.dtos[0].price: must not be null, submitForm.dtos[0].materialType: must not be null, submitForm.dtos[0].dateTo: must not be null, submitForm.dtos[0].client: must not be blank, submitForm.dtos[0].dateFrom: must not be null

    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1019)
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:914)
    at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:590)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885)
    at org.springframework.test.web.servlet.TestDispatcherServlet.service(TestDispatcherServlet.java:72)
    at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658)
    at org.springframework.mock.web.MockFilterChain$ServletFilterProxy.doFilter ....


Caused by: jakarta.validation.ConstraintViolationException: submitForm.dtos[0].client: must not be null, submitForm.dtos[0].priceType: must not be null, submitForm.dtos[0].price: must not be null, submitForm.dtos[0].materialType: must not be null, submitForm.dtos[0].dateTo: must not be null, submitForm.dtos[0].client: must not be blank, submitForm.dtos[0].dateFrom: must not be null
    at org.springframework.validation.beanvalidation.MethodValidationInterceptor.invoke(MethodValidationInterceptor.java:138)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:756)

知道如何解决这个问题吗?

java spring-boot spring-mvc spring-test spring-test-mvc
1个回答
0
投票

如果

MockMvc#perform()
抛出异常,则意味着您没有配置 spring-mvc 来处理此异常。(即您的情况下的
ConstraintViolationException
)。

实际上,异常将被传播回 Servlet 容器,让它处理将返回的 HTTP 响应。现在,当您使用

MockMvc
时,您可以认为
MockMvc
是一种 Servlet 容器,它的实现将简单地抛出从 spring-mvc 传播到它的任何异常。

所以答案是配置 spring-mvc 来处理

ConstraintViolationException
,例如为其声明一个
@ControllerAdvice
:

@ControllerAdvice
public class ApiExceptionHandler extends ResponseEntityExceptionHandler {

    @ExceptionHandler(ConstraintViolationException.class)
    @ResponseStatus(value = HttpStatus.BAD_REQUEST)
    public void handleConstraintViolationException(final ConstraintViolationException ex) {
        log.info("handle ConstraintViolationException blabla",ex);
    }
}

注意:请参阅this

了解如何在 spring-mvc 中处理异常
© www.soinside.com 2019 - 2024. All rights reserved.