Skip to content

Allow customization of TestDispatcherServlet when using @MockMvcTest [SPR-14277] #18849

@spring-projects-issues

Description

@spring-projects-issues

Mike Pleimann opened SPR-14277 and commented

I'm using spring-boot and attempting to test a @ControllerAdvice component with an exception handler method for NoHandlerFoundException. I've set spring.mvc.throw-exception-if-no-handler-found to true in application.yml which will set DispatcherServlet.throwExceptionIfNoHandlerFound true. 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 call setThrowExceptionIfNoHandlerFound on the TestDispatcherServlet as Boot's 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 seems to be no way to set this property.

A Github issue was opened but closed as the change would be needed in spring-test rather than boot.

@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;
    }
}

Affects: 4.3 RC2, 4.3 GA

Reference URL: spring-projects/spring-boot#5891

Referenced from: commits 30291a8, 1e3012c

0 votes, 5 watchers

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions