-
Notifications
You must be signed in to change notification settings - Fork 41.6k
Description
I'm attempting to test a @ControllerAdvice component with a, exception handler method for NoHandlerFoundException. I've set spring.mvc.throw-exception-if-no-handler-found to true in application.yml. When running the application as normal the DispatcherServlet throws the exceptions and they're handled appropriately. However, when attempting to test it with a @MockMvcTest, the NoHandlerFoundException is never thrown.
MockMvcBuilderSupport's constructor doesn't set the spring.mvc properties on the TestDispatcherServlet as DispatcherServletAutoConfiguration#DispatcherServletConfiguration does when building the DispatcherServlet. Because it's passed to the MockMvc constructor without adding to the ApplicationContext and the TestDispatcherServlet isn't accessible there's no way to set this property.
Using spring-boot v1.4.0 SNAPSHOT
@RunWith(SpringRunner.class)
@WebMvcTest(controllers = { RootController.class, ExceptionHandlerAdvice.class })
public class RootControllerTest {
@Autowired
private MockMvc mockMvc;
@Test
public void testNoHandler() throws Exception {
this.mockMvc.perform(get("/FOO"))
.andExpect(status().isBadRequest())
.andExpect(jsonPath("$.message").value(startsWith("Invalid Request")));
}
}
@RestControllerAdvice
class ExceptionHandlerController {
@ExceptionHandler(NoHandlerFoundException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public ErrorData noHandlerFoundHandler(NoHandlerFoundException e, HttpServletRequest request) {
String message = String.format("Invalid Request: %s", e.getMessage());
log.info(message);
return new ErrorData(e.getClass(), message, request.getRequestURL().toString());
}
@Data
public static class ErrorData {
private final Instant timestamp = Instant.now();
private final Class<? extends Exception> type;
private final String message;
private final String requestUrl;
}
}