Избегайте инициализации контроллеров при тестировании весенней загрузки HandlerInterceptor

Я пытаюсь найти правильную конфигурацию для тестирования HandlerInterceptor приложения Spring-boot с @MockBean зависимостями, но без инициализации всего пула компонентов, потому что некоторые контроллеры имеют @PostConstruct вызовы, которые нельзя имитировать (зная, что @Before вызов идет после @PostContruct Вызов контроллера).

На данный момент я пришел к этому синтаксису:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = Application.class)
public class MyHandlerInterceptorTest {
  @Autowired
  private RequestMappingHandlerAdapter handlerAdapter;
  @Autowired
  private RequestMappingHandlerMapping handlerMapping;
  @MockBean
  private ProprieteService proprieteService;
  @MockBean
  private AuthentificationToken authentificationToken;

  @Before
  public void initMocks(){
    given(proprieteService.methodMock(anyString())).willReturn("foo");
  }

  @Test
  public void testInterceptorOptionRequest() throws Exception {
    MockHttpServletRequest request = new MockHttpServletRequest();
    request.setRequestURI("/some/path");
    request.setMethod("OPTIONS");

    MockHttpServletResponse response = processPreHandleInterceptors(request);
    assertEquals(HttpStatus.OK.value(), response.getStatus());
  }
}

Но тест терпит неудачу, java.lang.IllegalStateException: Failed to load ApplicationContext потому что один RestController с вызовом @PostContruct пытается получить данные от proprieteService мока, которые в данный момент не были имитированы.

Итак, мой вопрос: как я могу запретить тестовому загрузчику Springboot инициализировать все мои контроллеры, которые 1: мне не нужны для теста, 2: триггерные вызовы, которые происходят до того, как я смогу что-то издеваться?


person Aphax    schedule 19.07.2017    source источник
comment
Напишите модульный тест, а НЕ интеграционный тест. Просто создайте экземпляр HandlerInterceptor, создайте макеты и внедрите их.   -  person M. Deinum    schedule 19.07.2017
comment
В таком случае, как имитировать зависимости @autowired в моем Interceptor? Мне потребуются специальные аннотации загрузки Spring, @SpringBootTest выполнял эту работу.   -  person Aphax    schedule 19.07.2017


Ответы (1)


@М. Deinum показал мне путь, и действительно, решение состояло в том, чтобы написать настоящий модульный тест. Меня беспокоило то, что мне нужно было заполнить эти @autowired зависимости в моем Intercepter, и я искал какую-то волшебную аннотацию. Но было проще просто отредактировать пользовательский WebMvcConfigurerAdapter и передать зависимости через конструктор следующим образом:

@Configuration
public class CustomWebMvcConfigurerAdapter extends WebMvcConfigurerAdapter {
  AuthentificationToken authentificationToken;

  @Autowired
  public CustomWebMvcConfigurerAdapter(AuthentificationToken authentificationToken) {
    this.authentificationToken = authentificationToken;
  }

  @Bean
  public CustomHandlerInterceptor customHandlerInterceptor() {
    return new CustomHandlerInterceptor(authentificationToken);
  }

  @Override
  public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(customHandlerInterceptor());
  }
}

И перехватчик:

public class CustomHandlerInterceptor implements HandlerInterceptor {
  private AuthentificationToken authentificationToken;

  @Autowired
  public CustomHandlerInterceptor(AuthentificationToken authentificationToken) {
    this.authentificationToken = authentificationToken;
  }

  @Override
  public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
  }
}

Надеюсь, это может помочь.

person Aphax    schedule 19.07.2017