添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
相关文章推荐
英俊的松球  ·  Fork Options and ...·  2 天前    · 
精明的领带  ·  How do I test for the ...·  2 天前    · 
英俊的针织衫  ·  Project Dependencies ...·  2 天前    · 
气宇轩昂的铅笔  ·  Building a Web Site ...·  23 小时前    · 
傻傻的开水瓶  ·  python - Seaborn ...·  1 年前    · 
虚心的牛肉面  ·  python 生成csv 下载 ...·  2 年前    · 
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

SpringBootTest with MockMvcBuilders stand alone setup is not loading my ControllerAdvice despite setting it

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
                An observation but the mixing of SpingBootTest and MockMvc - i appreciate it can be done in java. If you have a running test application which SpringBootTest provides then test the service via request/response. Use the MockMvc to test the specifics of your Controller class as a second test.
– emeraldjava
                May 28, 2021 at 7:11
  • 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.

  •