复杂单元测试启动类-只测试OpenFeign以及只测试Spring Data JPA

随着springboot应用工程规模越来越大,集成了较多的自动配置的程序,例如 Spring Data JPA, Spring Cloud OpenFeign, Apache Dubbo
有时会需要在本地运行测试,但要么因为数据库无法在办公网络环境连接,要么注册中心无法连接,这就导致本地完全无法运行。

运行 SpringBoot 单元测试,只测试 OpenFeign 的部分,不启动数据库,不启动 Dubbo。

  • SpringBoot 通过注解和元注解进行自动配置,可以通过某些注解例如 @EnableAutoConfiguration 的 exclude 进行排除。
  • Spring原生注解 @ComponentScan 有包扫描路径可以配置,也有 Filter 进行精确控制扫描范围,指定扫描的类型,正则表达式等
  • 阻止Dubbo启动

    找出Dubbo的自动配置类,规则: DubboXXXAutoConfiguration

    过程中,如果有遗漏就继续追加

    @EnableAutoConfiguration(exclude = {
        DubboAutoConfiguration.class,
        DubboRelaxedBindingAutoConfiguration.class,
        DubboEndpointMetadataAutoConfiguration.class,
        DubboEndpointAnnotationAutoConfiguration.class,
        DubboMetricsAutoConfiguration.class
    

    声明包扫描路径为OpenFeign

    Feign自己的注解:EnableFeignClients

    @EnableFeignClients(basePackages = "com.slankka.cloud.rpc.feign")
    

    复杂ComponentScan注解

  • 声明 OpenFeign 的 Client 所在包路径 basePackages
  • 声明 includeFilters
  • 通过注册限定FeignClient注解进行过滤
  • 通过正则表达式限定其他的某些额外需要的类(这些类受限于 basePackages)
  • 关闭 useDefaultFilters,防止自动扫描 @Components 注解
  • 有了以上严格规则限定,即便和这个类放在同一个包的其他启动入口,也不会意外启动

    //包路径限定 "com.slankka.cloud.rpc.feign", "com.slankka.cloud.server.listener"}
    //注解限定 FilterType.ANNOTATION, classes = {FeignClient.class}),
    //正则表达式限定 FilterType.REGEX, pattern = {".*ContextHolder"})
    public class TestOpenFeign {
    

    SpringBootTest 注解

  • @SpringBootConfiguration将上述注解放在一起作为应用类 TestOpenFeign.class
  • @ComponentScan(basePackages = {"com.slankka.cloud.rpc.feign", "com.slankka.cloud.server.listener"}, includeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {FeignClient.class}), @ComponentScan.Filter(type = FilterType.REGEX, pattern = {".*ContextHolder"}) , useDefaultFilters = false @EnableFeignClients(basePackages = "com.slankka.cloud.rpc.feign") @EnableAutoConfiguration(exclude...) @SpringBootConfiguration public class TestOpenFeign {
  • 新写一个 @SpringBootTest 作为入口
  • @RunWith(SpringRunner.class)
    @EnableAutoConfiguration
    @SpringBootTest(classes= TestOpenFeign.class)
    public class OpenFeignLauncher {
    

    另外,不用SpringBootTest启动类也可以,直接把TestOpenFeign当作正常类也可以

    手动初始化ApplicationContext,不使用 SpringBootTest

    public static ConfigurableApplicationContext init(String[] args) {
        closeDubboLogo();
        SpringApplication local = new SpringApplicationBuilder()
            .web(WebApplicationType.NONE)
            .sources(TestOpenFeign.class)
            .build();
        return local.run(args);
    public static void main(String[] args) {
        ConfigurableApplicationContext init = init(args);
        // run test methods
        init.close();
    

    如何在上述基础上,只测试 JPA 数据库

  • 在包扫描路径中追加 JpaConfig 所在包
  • 通过正则表达式限定 JpaConfig 类,防止初始化其他 @Configuration 类。
  • @ComponentScan( basePackages = {
        "com.slankka.cloud.config", //JPAConfig 所在包
        "com.slankka.cloud.rpc.feign"
        //...
        includeFilters... = {pattern =  { ".*JpaConfig" }} //JpaConfig也要被识别
    @EnableFeignClients(basePackages = "com.slankka.cloud.rpc.feign")
    @EnableAutoConfiguration(exclude...)
    @SpringBootApplication(scanBasePackageClasses = {JpaConfig.class})
    public class TestOpenFeignAndJPA {
    

    Configuring base package for component scan in Spring boot test