Тестирование RequestInterceptor на основе аннотаций

Я хотел сделать такую ​​собственную логику (записывать запрос и ответ) на некоторых маршрутах. Основываясь на некоторых исследованиях, я решил использовать RequestInterceptor на основе AnnotationBased. Это мой код перехватчика.

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.
        }
}

Теперь этот класс работает, как ожидалось, но мне не удалось выполнить модульное тестирование этой функции.

  • Сначала я подумал о том, чтобы попытаться создать объект HandlerMethod, но я никуда не денется.
  • Во-вторых, я попытался использовать PowerMokito. Это был мой тестовый код:

    @RunWith(PowerMockRunner.class)
    @PrepareForTest(CustomInterceptor.class)
    @PowerMockIgnore("javax.management.*")
    public class CustomInterceptorTest {
    @Test
    public void restAnnotationRecording_negetivecase() {
      HandlerMethod mockHandler = mock(HandlerMethod.class);
      PowerMockito.mockStatic(AnnotationUtils.class);
      when(AnnotationUtils.getAnnotation(mockHandler.getMethod(), 
           CustomRecord.class).thenReturn(null);
      // Verify file is not saved
    }
     // A spy is stubbed using when(spy.foo()).then() syntax. It is safer to stub spies - - with doReturn|Throw() family of methods. More in javadocs for Mockito.spy() methodcannot be saved.
    @Test
    public void restAnnotationRecording_happycase() {
        HandlerMethod mockHandler = mock(HandlerMethod.class);
        PowerMockito.mockStatic(AnnotationUtils.class);
        when(AnnotationUtils.getAnnotation(mockHandler.getMethod(), CustomRecord.class).thenReturn(mockAnnotation);
        // Verify file is saved
    }
    }
    
    • Это дает ошибку. Шпион заглушен с использованием синтаксиса when (spy.foo ()). Then (). Безопаснее заглушать шпионов с помощью семейства методов doReturn | Throw ().

Я хотел проверить, есть ли способ проверить перехватчик. Я новичок в Java, спасибо за помощь.

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
5
0
2 371
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете легко создать свой собственный HandlerMethod без издевательства. Есть конструктор, который принимает объект (контроллер) и Method (метод контроллера). Самый простой способ получить Method - просто вызвать в Class.getMethod(). Вам нужно просто создать фиктивный класс контроллера, а затем использовать этот класс для получения метода. Например

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

Другие вопросы по теме