测试 spring 启动 HandlerInterceptor 时避免控制器初始化
Avoid Controllers initialization when testing spring boot HandlerInterceptor
我正在尝试找到正确的配置来测试 HandlerInterceptor
Spring-boot 应用程序,具有 @MockBean
依赖性,但没有初始化整个 Bean 池,因为一些控制器有 @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
mock 获取数据,这些 mock 目前还没有被 mock。
所以我的问题是:如何防止 Springboot 测试加载器初始化我所有的控制器,其中 1:我不需要测试,2:在我可以模拟之前触发调用什么?
@M。 Deinum 向我展示了方法,确实解决方案是编写一个真正的单元测试。我担心的是我需要在我的 Intercepter
中填充那些 @autowired
依赖项,并且正在寻找一些神奇的注释。但是编辑自定义 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 {
}
}
希望对您有所帮助。
我正在尝试找到正确的配置来测试 HandlerInterceptor
Spring-boot 应用程序,具有 @MockBean
依赖性,但没有初始化整个 Bean 池,因为一些控制器有 @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
mock 获取数据,这些 mock 目前还没有被 mock。
所以我的问题是:如何防止 Springboot 测试加载器初始化我所有的控制器,其中 1:我不需要测试,2:在我可以模拟之前触发调用什么?
@M。 Deinum 向我展示了方法,确实解决方案是编写一个真正的单元测试。我担心的是我需要在我的 Intercepter
中填充那些 @autowired
依赖项,并且正在寻找一些神奇的注释。但是编辑自定义 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 {
}
}
希望对您有所帮助。