Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Learn more about Collectives
Teams
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Learn more about Teams
Ask Question
//Build the controller mock handler
mockMvc = MockMvcBuilders
.standaloneSetup(MyController.class)
.setControllerAdvice(new MyControllerAdvice())
//This also doesn't work
//.setHandlerExceptionResolvers(createExceptionResolver())
.build();
//This also did not work
private ExceptionHandlerExceptionResolver createExceptionResolver() {
ExceptionHandlerExceptionResolver exceptionResolver = new ExceptionHandlerExceptionResolver() {
protected ServletInvocableHandlerMethod getExceptionHandlerMethod(HandlerMethod handlerMethod, Exception exception) {
Method method = new ExceptionHandlerMethodResolver(MyControllerAdvice.class).resolveMethod(exception);
return new ServletInvocableHandlerMethod(new MyControllerAdvice(), method);
exceptionResolver.afterPropertiesSet();
return exceptionResolver;
* Tests passing bad input to see if our exception handler is called.
@Test
public void testBadRequest()
//Make a request object that has a bad input (e.g. bad date string)
MyRequest request = new MyRequest();
//Set the request values
request.setDate( "a" );
myController.getSomething( request );
catch (Exception e)
//It reaches here without ever reaching my controller advice in debugging
e.printStackTrace();
Controller advice:
@EnableWebMvc
@ControllerAdvice
@Component
public class MyControllerAdvice {
@ExceptionHandler(value = Exception.class)
public ResponseEntity<String> handleException(HttpServletRequest request, Exception exception) throws Exception
//This is never called (I'm using a debugger and have a breakpoint here)
return new ResponseEntity<String>(
"test",
HttpStatus.INTERNAL_SERVER_ERROR
–
MockMvcBuilders#standaloneSetup() receives Controller
objects as parameters, not the Class
objects. So it should be:
mockMvc = MockMvcBuilders
.standaloneSetup(new MyController())
.setControllerAdvice(new MyControllerAdvice())
.build();
You are calling myController.getSomething( request )
directly, while you should use previously built mockMvc
. Direct call is unadvised as it's not processed with TestDispatcherServlet
. Here is a couple of examples for mockMvc
requests:
mockMvc.perform(get("/testSomething"))
.andExpect(status().is5xxServerError())
.andReturn();
mockMvc.perform(post("/testSomething")
.contentType(MediaType.APPLICATION_JSON)
.content(json)) //it's JSON string
.andExpect(status().is5xxServerError())
.andReturn();
You are trying to serialize to json a mocked bean. To simplify things, run this test, and you'll get the same error:
@Test
public void test() throws Exception {
var dto = Mockito.mock(EmployeeDTO.class);
var mapper = new ObjectMapper();
mapper.writeValueAsString(dto); // will throw the same exception
To fix it, you might need to rethink your design. Why are you declaring this DTO as a @Component and why do you mock it? Perhaps a better solution would be to have to keep this DTO as a POJO (Plain Old Java Object) and use a Service to will retrieve it. This way you will be able to mock the service and force it to return a specific employee for tests.
As a rule of thumb, we should mock roles/behavior, not data.
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.