您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

让我的Spring测试片扫描单个类而不是整个包

让我的Spring测试片扫描单个类而不是整个包

可以将 组件和服务配置为产生过滤器,因此我们可以指定目标服务和控制器,并同时排除其他所有内容

 @ComponentScan(
        basePackageClasses = {
                MyTargetService.class,
                MyTargetController.class
        },
        useDefaultFilters = false,
        includeFilters = {
                @ComponentScan.Filter(type = ASSIGNABLE_TYPE, value = MyTargetService.class),
                @ComponentScan.Filter(type = ASSIGNABLE_TYPE, value = MyTargetController.class)

        }
)

这不太可能适用于存储库,但幸运的是,@EnableJpaRepositories支持相同类型的过滤器:

  @EnableJpaRepositories(
       basePackageClasses = {
            MyTargetRepository.class
       },
       includeFilters = {
            @ComponentScan.Filter(type = ASSIGNABLE_TYPE, value = MyTargetRepository.class)
       }
  )

这部分比较棘手,因为@EntityScan不支持这些过滤器。尽管这些实体未引用Spring Bean,但我更喜欢仅加载测试所需的实体。我找不到支持过滤的实体的任何注释,但是我们可以使用中的来PersistenceUnitPostProcessor以编程方式过滤它们EntityManagerFactory。这是我的完整解决方案:

   //add also the filtered @ComponentScan and @EnableJpaRepositories annotations here
   @Configuration
   public class MyConfig {

    //here we specify the packages of our target entities
    private static String[] MODEL_PACKAGES = {
            "com.full.path.to.entity.package1",
            "com.full.path.to.entity.package2"
    };

    //here we specify our target entities
    private static Set<String> TARGET_ENTITIES = new HashSet<>(Arrays.asList(
            "com.full.path.to.entity.package1.MyTargetEntity1",
            "com.full.path.to.entity.package2.MyTargetEntity2"
    ));

    @Bean
    public DataSource getDataSource() {
        EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
        return builder.setType(EmbeddedDatabaseType.H2).build();
    }

    @Bean
    public EntityManagerFactory entityManagerFactory() {

        ReflectionsPersistenceUnitPostProcessor reflectionsPersistenceUnitPostProcessor = new ReflectionsPersistenceUnitPostProcessor();

        HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        vendorAdapter.setGenerateDdl(true);
        vendorAdapter.setShowsql(true);

        LocalContainerEntityManagerfactorybean factory = new LocalContainerEntityManagerfactorybean();
        factory.setJpaVendorAdapter(vendorAdapter);
        factory.setPackagesToScan(MODEL_PACKAGES);
        factory.setDataSource(getDataSource());
        factory.setPersistenceUnitPostProcessors(reflectionsPersistenceUnitPostProcessor);
        factory.afterPropertiesSet();

        return factory.getObject();
    }


    @Bean
    public PlatformTransactionManager transactionManager() {
        JpaTransactionManager txManager = new JpaTransactionManager();
        txManager.setEntityManagerFactory(entityManagerFactory());
        return txManager;
    }

    public class ReflectionsPersistenceUnitPostProcessor implements PersistenceUnitPostProcessor {

        @Override
        public void postProcessPersistenceUnitInfo(MutablePersistenceUnitInfo pui) {

            Reflections r = new Reflections("", new TypeAnnotationsScanner());
            Set<Class<?>> entityClasses = r.getTypesAnnotatedWith(Entity.class, true);
            Set<Class<?>> mappedSuperClasses = r.getTypesAnnotatedWith(MappedSuperclass.class, true);

            pui.getManagedClassNames().clear(); //here we remove all entities

            //here we add only the ones we are targeting
            for (Class<?> clzz : mappedSuperClasses) {
                if (TARGET_ENTITIES.contains(clzz.getName())) {
                    pui.addManagedClassName(clzz.getName());
                }
            }
            for (Class<?> clzz : entityClasses) {
                if (TARGET_ENTITIES.contains(clzz.getName())) {
                    pui.addManagedClassName(clzz.getName());
                }
            }

        }

    }


}
Java 2022/1/1 18:19:16 有457人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶