Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test a Spring Boot handler Interceptor

we are trying to do an intergration test our interceptors in our spring boot application using spring boot version 1.4.0, but not sure how; here is our application setting

@Configuration
@EnableAutoConfiguration()
@ComponentScan
public class Application extends SpringBootServletInitializer {
  @Override
  protected SpringApplicationBuilderconfigure(SpringApplicationBuilder application) {
  return application.sources(Application.class);
}

we then customed out webmvc by extending WebMvcConfigurerAdapter

@Configuration
public class CustomServletContext extends WebMvcConfigurerAdapter{
  @Override
  public void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(testInterceptor).addPathPatterns("/testapi/**");
  }
}

so we wanna to test the interceptor, but we don't wanna really start the application, cause there are many dependency beans that need to read a externally defined property files to construct

we have tried the following

@SpringBootTest(classes = CustomServletContext.class)
@RunWith(SpringRunner.class)
public class CustomServletContextTest {

  @Autowired
  private ApplicationContext applicationContext;

  @Test
  public void interceptor_request_all() throws Exception {
    RequestMappingHandlerMapping mapping = (RequestMappingHandlerMapping) applicationContext
        .getBean("requestMappingHandlerMapping");
    assertNotNull(mapping);

    MockHttpServletRequest request = new MockHttpServletRequest("GET",
        "/test");

    HandlerExecutionChain chain = mapping.getHandler(request);

    Optional<TestInterceptor> containsHandler = FluentIterable
        .from(Arrays.asList(chain.getInterceptors()))
        .filter(TestInterceptor.class).first();

    assertTrue(containsHandler.isPresent());
  }
}

but it alters org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'requestMappingHandlerMapping' is defined

Do we need to create a bean of requestMappingHandlerMapping to test the interceptors? is there any magical way to do this in spring boot ?

like image 907
sthbuilder Avatar asked Oct 02 '17 18:10

sthbuilder


People also ask

How do you call an interceptor from a spring boot?

To work with interceptor, you need to create @Component class that supports it and it should implement the HandlerInterceptor interface. preHandle() method − This is used to perform operations before sending the request to the controller. This method should return true to return the response to the client.

What is Handler interceptor in spring boot?

Simply put, a Spring interceptor is a class that either extends the HandlerInterceptorAdapter class or implements the HandlerInterceptor interface. The HandlerInterceptor contains three main methods: prehandle() – called before the execution of the actual handler. postHandle() – called after the handler is executed.

How do you call an interceptor in Java?

Use the @AroundInvoke annotation to designate interceptor methods for managed object methods. Only one around-invoke interceptor method per class is allowed. Around-invoke interceptor methods have the following form: @AroundInvoke visibility Object method-name(InvocationContext) throws Exception { ... }


1 Answers

You can create a test like this :

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = { MyIncludedConfig.class })
@ActiveProfiles("my_enabled_profile")
public class BfmSecurityInterceptorTest2 {

    public static final String TEST_URI = "/test";
    public static final String RESPONSE = "test";

    // this way you can provide any beans missing due to limiting the application configuration scope
    @MockBean
    private DataSource dataSource;

    @Autowired
    private TestRestTemplate testRestTemplate;

    @Test
    public void testInterceptor_Session_cookie_present_Authorized() throws Exception {

        ResponseEntity<String> responseEntity = testRestTemplate.getForEntity(TEST_URI, String.class);

        assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK);
        assertThat(responseEntity.getBody()).isEqualTo(RESPONSE);

    }

    @SpringBootApplication
    @RestController
    public static class TestApplication {

        @GetMapping(TEST_URI)
        public String test() {
            return RESPONSE;
        }

    }

}

Notes

  • Interceptors only work if you set SpringBootTest.WebEnvironment.RANDOM_PORT
  • You have to provide enough configuration so your interceptors are executed
  • To speed up the test you can exclude not wanted beans and configurations, see examples
like image 109
Peter Szanto Avatar answered Sep 19 '22 05:09

Peter Szanto