I have the following Spring test class:
@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());
}
}
however, instead of spring-application container returning bad-request (for @NotNull annotated fields), it throws the following error:
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)
any idea how this can be fixed?
If
MockMvc#perform()throws exception , it implies you do not configure spring-mvc to handle this exception.(i.eConstraintViolationExceptionin your case).In reality, the exception will be propagated back to the servlet container to let it handle (e.g decide what HTTP response will be returned etc).But now as you are using
MockMvc, you can think that it is a mocked version of servlet container which its implementation is just throw the exception for any exception propagated to it.So the answer is to configure spring-mvc to handle
ConstraintViolationException, for example by declaring a@ControllerAdvicefor it :Note : See more how to handle exception in spring-mvc at this