测试基于注解的 RequestInterceptor

Testing Annotation based RequestInterceptor

我想在某些路由上执行自定义逻辑(记录请求和响应)。基于一些研究,我决定使用 AnnotationBased RequestInterceptor。这是我的拦截器代码。

public class CustomInterceptor extends HandlerInterceptorAdapter {
@Override
public void afterCompletion(final HttpServletRequest request,
                            final HttpServletResponse response,
                            final Object handler,
                            final Exception ex) {
     if (handler != null && handler instanceof  HandlerMethod) {
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        CustomRecord annotation = AnnotationUtils.getAnnotation(handlerMethod.getMethod(), CustomRecord.class);
        if (annotation != null) {
              // Record Request and Response in a File.
        }
}

现在这个 class 按预期工作,但我无法对该函数进行单元测试。

我想看看有没有什么方法可以测试拦截器。我是Java的新手,谢谢帮助。

您无需模拟即可轻松创建自己的 HandlerMethod。有一个 constructor 接受一个对象(控制器)和一个 Method (控制器方法)。获得 Method 的最简单方法是简单地调用 Class.getMethod()。您要做的只是创建一个虚拟控制器 class,然后使用该 class 获取方法。例如

class TestController {
    @Custom
    public void testMethod() {}
}

Method method = TestController.class.getMethod("testMethod");
TestController controller = new TestController();
HandlerMethod handlerMethod = new HandlerMethod(controller, method);

Custom annotation = handlerMethod.getMethodAnnotation(Custom.class);

就这么简单。下面是一个完整的测试。

public class HandlerInterceptorTest {

    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    private @interface Custom {
    }

    private static class MyHandlerInterceptor implements HandlerInterceptor {

        @Override
        public boolean preHandle(HttpServletRequest req, HttpServletResponse res, Object handler) {
            if (handler instanceof HandlerMethod) {
                HandlerMethod handlerMethod = (HandlerMethod) handler;
                Custom annotation = handlerMethod.getMethodAnnotation(Custom.class);
                if (annotation != null) {
                    return true;
                }
            }
            return false;
        }
    }

    private static class TestController {
        @Custom
        public void testMethodWithAnnotation() {}

        public void testMethodWithoutAnnotation() {}
    }

    @Test
    public void testMethodWithAnnotation() throws Exception {
        Method method = TestController.class.getMethod("testMethodWithAnnotation");
        TestController controller = new TestController();
        HandlerMethod handlerMethod = new HandlerMethod(controller, method);

        MyHandlerInterceptor interceptor = new MyHandlerInterceptor();
        boolean result = interceptor.preHandle(null, null, handlerMethod);

        assertTrue(result);
    }

    @Test
    public void testMethodWithoutAnnotation() throws Exception {
        Method method = TestController.class.getMethod("testMethodWithoutAnnotation");
        TestController controller = new TestController();
        HandlerMethod handlerMethod = new HandlerMethod(controller, method);

        MyHandlerInterceptor interceptor = new MyHandlerInterceptor();
        boolean result = interceptor.preHandle(null, null, handlerMethod);

        assertFalse(result);
    }
}