I am having a SimpleTest :
@RunWith(SpringRunner.class)
@SpringBootTest(classes = SimpleTestConfig.class)
public class SimpleTest {
@Test
public void test() {
assertThat(true);
}
}
and a configuration for this test :
@SpringBootApplication
@ComponentScan(basePackageClasses = {
SimpleTestConfig.class,
Application.class
},
excludeFilters = @ComponentScan.Filter(
type = FilterType.ASSIGNABLE_TYPE,
classes = Starter.class))
public class SimpleTestConfig {
}
I am trying to exclude the Starter class
package application.starters;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
@Component
public class Starter {
@PostConstruct
public void init(){
System.out.println("initializing");
}
}
And the Application class looks like this :
package application;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import static org.springframework.boot.SpringApplication.run;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
run(Application.class, args);
}
}
But for a very weird reason the Starter class is still getting initialized.
Can anyone explain why the ComponentScan excludeFilters
is not excluding my Starter
class ?
16.2 Disabling Specific Auto-configuration Classes If the class is not on the classpath, you can use the excludeName attribute of the annotation and specify the fully qualified name instead. Finally, you can also control the list of auto-configuration classes to exclude by using the spring. autoconfigure.
Actually the @SpringBootApplication annotation is equivalent to using @Configuration , @EnableAutoConfiguration and @ComponentScan with their default attributes.
exclude , not excludes as in the release notes. This helps prevent Spring Boot from loading autoconfig classes in the presence of multiple @EnableAutoConfiguration / @SpringBootApplication annotations.
To disable the default filter, set the useDefaultFilters element of the @ComponentScan annotation to false.
Each component scan does filtering individually. While you exclude Starter.class
from SimpleTestConfig
, SimpleTestConfig
initializes Application
, which does it's own @ComponentScan
without excluding Starter
.
The clean way of using ComponentScan is for each ComponentScan to scan separate packages, that way each filter works fine. When 2 separate ComponentScans scan the same package (as in your tests), this does not work.
One way to trick this is to provide a mock Starter
bean:
import org.springframework.boot.test.mock.mockito.MockBean;
public class SimpleTest {
@MockBean
private Starter myTestBean;
...
}
Spring will use that mock instead of the real class, thus the @PostConstruct
method will not be called.
Other common solutions:
Application.class
in any unit test@Profile("!TEST")
on the Starter
class@ConditionalOn...
annotation on the Starter
classIf you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With