Как издеваться над Spring HandlerInterceptorAdapter в интеграционном тесте?

Скажем, у меня есть FooInterceptor:

public class FooInterceptor extends HandlerInterceptorAdapter {
   // ...
}

Что настроено в контексте:

 <mvc:interceptors>
     <mvc:interceptor>
        <mvc:mapping path = "/**"/>
        <bean class = "my.package.FooInterceptor"/>
     </mvc:interceptor>
 </mvc:interceptors>

Я создаю интеграционный тест для какого-то контроллера:

@WebAppConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(value = "/context.xml")
@ActiveProfiles("test")
public class SomeControllerIT {

    @Autowired
    private WebApplicationContext webApplicationContext;

    private MockMvc mockMvc;

    @Before
    public void setup() {
        mockMvc = MockMvcBuilders
                .webAppContextSetup(webApplicationContext)
                .apply(springSecurity())
                .build();
    }

    ...
}

Я попытался издеваться над этим, создав собственную конфигурацию:

@Configuration
static class Config {

    @Bean
    @Primary
    public FooInterceptor getFooInterceptor() {
        return mock(FooInterceptor.class);
    }
}

Но мне кажется, что это не работает. Настоящий FooInterceptor все еще производится и участвует в тестировании.

Как правильно поиздеваться?

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

Ответы 3

Итак, я пошел дальше и написал код, чтобы решить тот же вопрос, который у меня был. В нашем проекте тестового примера мы можем имитировать перехватчик, явно определив наш собственный перехватчик, который расширяет HandlerInterceptorAdapter, который будет иметь фиктивную логику, имитирующую наш исходный перехватчик.

public class MockTenantInterceptor extends HandlerInterceptorAdapter

Мы можем инициализировать фиктивный класс перехватчика без автоматического подключения и приступить к его регистрации в классе TestConfiguration. Убедитесь, что у нас будет 2 класса конфигурации, один для WebConfig и TestConfig, чтобы добавить аннотацию профиля пружины, которая предотвращает вызов вашего производственного перехватчика.

@Profile("test")
@TestConfiguration
@EnableJpaAuditing
public class TestConfig extends WebMvcConfigurerAdapter {


    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        MockTenantInterceptor mockTenantInterceptor = new MockTenantInterceptor();
        registry.addInterceptor(mockTenantInterceptor);
    }
}

Обновлено: в Spring 5 / Spring Boot 2 extends WebMvcConfigurerAdapter устарел в пользу implements WebMvcConfigurer и использует новые методы по умолчанию Java 8 для интерфейсов.

См. https://www.baeldung.com/web-mvc-configurer-adapter-deprecated

Разве просто ввести перехватчик не проще и чище?

private MockMvc mockMvc;

@MockBean
private MyInterceptor interceptor;

@BeforeEach
public void before() {
  MockitoAnnotations.initMocks(this);
  mockMvc = MockMvcBuilders
      .standaloneSetup(controller)
      .addInterceptors(interceptor)
      .build();
}

Вы можете пойти со следующим, как предложила Луана FM в предыдущем ответе. Также вам понадобится одна строка фиктивного кода, чтобы вернуть ответ перехватчика как правда в блоке @BeforeEach.

        @BeforeEach
        public void before() {
          MockitoAnnotations.initMocks(this);
          mockMvc = MockMvcBuilders
              .standaloneSetup(controller)
              .addInterceptors(interceptor)
              .build();
        when(interceptor.preHandle(Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(true);
    
        }

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