问题
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