问题描述
我正在尝试找到正确的配置以测试具有@MockBean
依赖项的Spring-boot应用程序的HandlerInterceptor
,但没有初始化整个Bean池,因为某些控制器具有无法调用的@PostConstruct
调用被嘲笑(知道@Before
调用是在@PostContruct
控制器调用之后).
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());
}
}
但是测试失败,java.lang.IllegalStateException: Failed to load ApplicationContext
,因为一个具有@PostContruct调用的RestController
试图从此时尚未被模拟的proprieteService
模拟中获取数据.
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.
所以我的问题是:如何阻止Springboot测试加载程序初始化我的所有Controller,其中1:我不需要测试,2:触发可以在模拟任何东西之前发生的调用?
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 ?
推荐答案
@M. Deinum向我展示了方法,实际上解决方案是编写一个真正的单元测试.我担心的是,我需要在我的Intercepter
中填充那些@autowired
依赖项,并且正在寻找一些魔术注释.但是,只需编辑自定义WebMvcConfigurerAdapter
并通过如下所示的构造函数传递依赖项,就更简单了:
@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());
}
}
和拦截器:
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 {
}
}
希望这会有所帮助.
这篇关于在测试Spring Boot HandlerInterceptor时避免控制器初始化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!