Avoid Controllers initialization when testing spring boot HandlerInterceptor

僤鯓⒐⒋嵵緔 提交于 2019-12-12 04:11:50

问题


I'm trying to find the right configuration for testing HandlerInterceptor of a Spring-boot application, with @MockBean dependencies, but without initializing the whole Bean pool, because some Controllers have @PostConstruct calls that can't be mocked (knowing that @Before call comes after @PostContruct Controller call).

For now I have come to this syntax :

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

But test fails, java.lang.IllegalStateException: Failed to load ApplicationContext because one RestController having a @PostContruct call tries to get data from proprieteService mock who have not been mocked at this moment.

So my question is : how can I prevent Springboot test loader to initialize all my Controllers, which 1: I don't need for the test, 2: Trigger calls that happen before I can mock anything ?


回答1:


@M. Deinum showed me the way, indeed the solution was to write a real Unit test. My concern was that I needed to populate those @autowired dependencies in my Intercepter, and was searching for some magic annotation. But it was simpler to just edit the custom WebMvcConfigurerAdapter and pass the dependencies via constructor like this :

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

And interceptor :

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

Hope this can help.



来源:https://stackoverflow.com/questions/45191819/avoid-controllers-initialization-when-testing-spring-boot-handlerinterceptor

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!