本文介绍了在测试Spring Boot HandlerInterceptor时避免控制器初始化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试找到正确的配置以测试具有@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时避免控制器初始化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-29 20:53
查看更多