I have a production service that utilizes spring-boot-starter-test and JUnit annotations to execute test scenarios on my production environment as a sort of smoke/automation test engine.
When upgrading this service to Spring Boot 3.1.x, I found out that it stopped scanning all of the classes annotated both with @Test and @Component. This worked fine up until and including version 3.0.9.
I'm aware that TestTypeExcludeFilter exists and has been around for a while. However, in the Spring Boot server run, up until version 3.0.9, there were no delegates in the TypeExcludeFilter's delegate list. In 3.1.x, an initializer was added called ExcludeFilterApplicationContextInitializer, and it registered TestTypeExcludeFilter in the context, which is causing issues for my server.
I will provide my workaround in a comment.
My request here is: Can we revert to the previous default behavior? If not, can we add a configuration option to override this new default?
Thanks, Alex
Comment From: alexfeigin
my workaround:
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.ApplicationContextInitializer;
@SpringBootApplication
public class Server {
private final static String TestTypeExcludeFilter = "org.springframework.boot.test.context.filter.TestTypeExcludeFilter";
public static void main(String[] args) {
SpringApplication springApplication = new SpringApplication(Server.class);
// prepend an ApplicationContextInitializer which will nuke TestTypeExcludeFilter
List<ApplicationContextInitializer<?>> initializers = new ArrayList<>();
initializers.add(applicationContext -> {
ConfigurableListableBeanFactory beanFactory = applicationContext.getBeanFactory();
beanFactory.registerSingleton(TestTypeExcludeFilter, new Object());
});
initializers.addAll(springApplication.getInitializers());
springApplication.setInitializers(initializers);
springApplication.run(args);
}
}
Comment From: quaff
I think it should be keep as it is since it's a rare use case, and your workaround should use springApplication.addInitializers() instead of springApplication.setInitializers().
Comment From: wilkinsona
I think it's very unlikely that we'll just revert the change as it would regress the fix for SpringApplication.from that introduced the context initializer.
An alternative would be to rework #35206 such that we have some other customizer contract for SpringApplication.from but I'm not sure that added complexity is worth the benefit to what is a niche use case. We'll have to discuss it as a team and see what we want to do.
Comment From: wilkinsona
We discussed this today and agreed that this isn't something that we want to support. spring-boot-starter-test isn't intended for use in a "production" environment and the approach taken here isn't something that we want to encourage. Thanks anyway for bringing the change in behavior to our attention.
Comment From: alexfeigin
Sorry for late response on a closed ticket, but adding this just for completeness of documentation. @quaff When testing the 'add' option, the real TestTypeExcludeFilter gets registered before my initializer gets called, and my initializer fails because there is already a bean with that name.
The init order is important so I had to create a 'prepend' behaviour, there is no native prepend function like springApplication.prependInitializer or springApplication.addInitializer(x,priority) so I had get the list, create a copy with my initializer at the top, and then set my list instead of the real list.