I have this JUnit 5 test:
@SpringBootTest
public class MyTest {
...
}
The application default configuration loads many @Component
's @Service
's and @Configuration
's.
For some tests, I would like to tell the Spring application running in this JUnit test context to not scan all the components and filter out some heavy loading or verbose/spammy components that might complain while running in a (mocked) environment where not all the requirements are met.
I tried to provide the @ComponentScan annotation to MyTest
class in the form below. I added on purpose multiple filters and multiple types being filtered with the hope that I see less beans being loaded/registered in the application context:
@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(), ...);
}
}
Regardless what I provide to the @CompoenntScan
, I don't manage to control the amount or what beans are being scanned/registered in the JUnit 5 Spring test context.
But I still want to use the @SpringBootTest
in order to get most of my application's configuration but exclude some parts of it (because they are slow, or spammy in the logs, or just throwing errors). For example, an application that receives event from inputs like Kafka, RabbitMQ, or REST, processes them and saves them to the persistence layer. I want to test the processing and persistence integration. I throw a bunch of test events to the processor @Service
and then expect to see the results in the DB via the @Repository
.
What would be my alternatives:
- provide @SpringBootTest a whitelist of classes I want to load (not elegant, tedious)
- define several Spring profiles, put condition annotations on component and activate/deactivate only the ones I need in the test code, also use different profile
application-*.properties
to mute some logging (the non-test code needs to be polluted with this test feature, and tedious creating multiple profiles) - other ways to build the application context from scratch (while I actually want is to use my application configuration, except some slices which are not relevant for certain tests)