Java 在运行JUnit5测试时,如何覆盖Spring组件扫描?

Java 在运行JUnit5测试时,如何覆盖Spring组件扫描?,java,spring,spring-boot,junit5,component-scan,Java,Spring,Spring Boot,Junit5,Component Scan,我有一个JUnit 5测试: @SpringBootTest public class MyTest { ... } 应用程序默认配置加载许多@组件@服务和@配置 对于一些测试,我想告诉在这个JUnit测试上下文中运行的Spring应用程序不要扫描所有组件,并过滤掉一些重载或冗长/垃圾组件,这些组件在(模拟的)环境中运行时可能会抱怨,而不是满足所有要求 我试图以下面的形式向MyTest类提供@ComponentScan注释。我特意添加了多个过滤器和多个被过滤的类型,希望在应用程序上下文中

我有一个JUnit 5测试:

@SpringBootTest
public class MyTest {
   ...
}
应用程序默认配置加载许多
@组件
@服务
@配置

对于一些测试,我想告诉在这个JUnit测试上下文中运行的Spring应用程序不要扫描所有组件,并过滤掉一些重载或冗长/垃圾组件,这些组件在(模拟的)环境中运行时可能会抱怨,而不是满足所有要求

我试图以下面的形式向
MyTest
类提供@ComponentScan注释。我特意添加了多个过滤器和多个被过滤的类型,希望在应用程序上下文中加载/注册的bean更少:

@ComponentScan(
    useDefaultFilters = false,
    excludeFilters = {
        @Filter(type = FilterType.ANNOTATION, classes = {
            org.springframework.context.annotation.Configuration.class,
            org.springframework.stereotype.Service.class,
            org.springframework.stereotype.Component.class
        }),
        @Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {
            MyRabbitMqListener.class
        })
    }
)
@SpringBootTest
public class MyTest {

    @Autowired
    private ApplicationContext context;

    @Test
    public void expectingLessRegisteredBeans() {
        List<String> beans = Arrays.stream(context.getBeanDefinitionNames())
               // ...
               .collect(Collectors.toList());
        assertEquals(beans.size(), ...);
    }

}
@ComponentScan(
useDefaultFilters=false,
排除过滤器={
@过滤器(类型=FilterType.ANNOTATION,类={
org.springframework.context.annotation.Configuration.class,
org.springframework.stereotype.Service.class,
org.springframework.stereotype.Component.class
}),
@过滤器(类型=FilterType.ASSIGNABLE_类型,类={
MyRabbitMqListener.class
})
}
)
@春靴测试
公共类MyTest{
@自动连线
私有应用程序上下文上下文;
@试验
public void expectingLessRegisteredBeans(){
List bean=Arrays.stream(context.getBeanDefinitionNames())
// ...
.collect(Collectors.toList());
assertEquals(beans.size(),…);
}
}
无论我向
@componentscan
提供了什么,我都无法控制JUnit 5 Spring测试上下文中扫描/注册的bean数量

但是我仍然希望使用
@springbootest
来获取我的应用程序的大部分配置,但排除其中的一些部分(因为它们速度慢,或者日志中有垃圾,或者只是抛出错误)。例如,从Kafka、RabbitMQ或REST等输入接收事件的应用程序会处理这些事件并将其保存到持久性层。我想测试处理和持久性集成。我向处理器
@Service
抛出一系列测试事件,然后期望通过
@Repository
在数据库中看到结果

我的备选方案是什么:

  • 为@SpringBootTest提供我想要加载的类的白名单(不优雅,乏味)
  • 定义多个Spring配置文件,在组件上放置条件注释,并仅激活/停用测试代码中需要的配置文件,还可以使用不同的配置文件
    application-*.properties
    禁用一些日志记录(非测试代码需要被此测试功能污染,并且创建多个配置文件非常繁琐)
  • 从头开始构建应用程序上下文的其他方法(虽然我实际上希望使用的是我的应用程序配置,但与某些测试无关的部分除外)

然后不要使用
@SpringBootTest
,因为这是用于完全集成测试的。如果您想要其他东西,可以使用切片测试(
@WebMvcTest
),编写适当的单元测试(使用mock),或者使用具有专用测试上下文的常规Spring测试。我想编写一个与Kafka、Rabbit和Rest输入无关的测试。我仍在尝试编写集成测试,以获取不同的消息并将它们发送到服务/处理器,然后我希望在Oracle或H2 DB中看到预期的结果。一些存储库查询需要Oracle内置的JSON_查询查询功能,因此我必须对这些功能进行集成测试。删除
@ComponentScan
内容,而是通过
@SpringBootTest
注释上的
classes
属性定义Spring应该管理哪些类,例如:
@SpringBootTest(webEnvironment=SpringBootTest.webEnvironment.NONE,classes={Config1.class,Config2.class,SomeAutoConfiguration.class,Component1.class,Service2.class})
。可以找到一些仅包含无环境和2个类(测试中的服务及其背后的存储库)的进一步信息。应用程序无法加载:
至少需要1个符合autowire候选条件的bean。依赖项注释:{@org.springframework.beans.factory.annotation.Autowired(required=true)}
。该错误抱怨找不到存储库类,因此无法在测试类中自动连接服务。但是,如前所述,服务和存储库都在classes注释参数中提供:(