java - 带有 MockMvcBuilders 的 SpringBootTest 独立设置没有加载我的 ControllerAdvice 尽管设置了它

标签 java spring spring-mvc spring-boot spring-boot-test

我正在这样创建我的 Controller 和 Controller 建议:

测试类:

@RunWith(SpringRunner.class)
@SpringBootTest
public class TestController {

    private MockMvc mockMvc;

    @Mock
    private MyService myService;

    @Autowired
    @InjectMocks
    private MyController myController;

    @Before
    public void setup() {

        MockitoAnnotations.initMocks(this);

        //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" );

        try
        {
            myController.getSomething( request );
        }
        catch (Exception e)
        {
            //It reaches here without ever reaching my controller advice in debugging
            e.printStackTrace();
        }
    }
}

Controller 建议:

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

最佳答案

你的例子有两个问题:

  1. MockMvcBuilders#standaloneSetup()接收 Controller 对象作为参数,而不是 Class 对象。所以应该是:

    mockMvc = MockMvcBuilders
            .standaloneSetup(new MyController())
            .setControllerAdvice(new MyControllerAdvice())
            .build();
    
  2. 您正在直接调用 myController.getSomething( request ),而您应该使用之前构建的 mockMvc。不建议直接调用,因为它未使用 TestDispatcherServlet 进行处理。以下是 mockMvc 请求的几个示例:

获取

    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();

关于java - 带有 MockMvcBuilders 的 SpringBootTest 独立设置没有加载我的 ControllerAdvice 尽管设置了它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46269598/

相关文章:

java - 选择并执行案例后重复切换案例

java - Spring 看不到 servlet-context 和 contextConfigLocation bean 之间的 bean

java - Spring 的 bean 验证不起作用

java - 当我使用 CookieLocaleResolver 时,我可以设置无效的 cookie 来使 Spring Web 应用程序崩溃

java - 使用 JAXB 创建带有 XSD 的 XML

java - 单例模式在实际应用中到底在哪里使用?

java - 使用itemTouchViewer在Recyclerview中拖放不影响动画

spring - 是 8.5.5.2 : No spring webapplicationinitializer types detected on classpath

spring-mvc - Spring Boot/MVC 通过注解过滤

java - REST api 中的版本控制资源