如何测试弹簧启动处理程序拦截器



我们正在尝试使用Spring Boot版本1.4.0在Spring Boot应用程序中进行分解测试,但不确定如何;这是我们的应用程序设置

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

然后,我们通过扩展WebMvcconfigurerAdapter

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

因此,我们想测试拦截器,但我们不想真正启动应用程序,因为有许多依赖性bean需要读取外部定义的属性文件才能构造

我们尝试了以下

@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());
  }
}

,但它会改变org.springframework.beans.factory.nosuchbeandefinitionException:no no bean被定义为'requestMappingHandLermpapping'

我们是否需要创建一个requestMappingHandLermpapping的bean来测试拦截器?有没有神奇的方法可以在Spring Boot中执行此操作?

您可以创建这样的测试:

@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;
        }
    }
}

注释

  • 拦截器仅在设置springboottest.webenvironment.random_port
  • 时才能工作
  • 您必须提供足够的配置,以便执行拦截器
  • 为了加快测试的速度,您可以不排除想要的豆类和配置,请参见示例
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.web.servlet.HandlerExecutionChain;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import java.util.Optional;
import static org.junit.jupiter.api.Assertions.assertTrue;
@SpringBootTest()
class LoggingInterceptorConfigurationTest {
    @Autowired
    private RequestMappingHandlerMapping mapping;
    @Test
    public void LoggingInterceptorShouldBeApplied() throws Exception {
        MockHttpServletRequest request = new MockHttpServletRequest("GET", "/api/example");
        HandlerExecutionChain chain = mapping.getHandler(request);
        assert chain != null;
        Optional<HandlerInterceptor> LoggingInterceptor = chain.getInterceptorList()
                .stream()
                .filter(LoggingInterceptor.class::isInstance)
                .findFirst();
        assertTrue(LoggingInterceptor.isPresent());
    }
    @Test
    public void LoggingInterceptorShouldNotBeAppliedToHealthURL() throws Exception {
        MockHttpServletRequest request = new MockHttpServletRequest("GET", "/health");
        HandlerExecutionChain chain = mapping.getHandler(request);
        assert chain != null;
        Optional<HandlerInterceptor> LoggingInterceptor = chain.getInterceptorList()
                .stream()
                .filter(LoggingInterceptor.class::isInstance)
                .findFirst();
        assertTrue(LoggingInterceptor.isEmpty());
    }
}

最新更新