How to integration test auto configuration for a custom Spring Boot style starter library?
I was able to make it work with the following test class:
@SpringBootTest
@ContextConfiguration(classes = TestApplication)
class DummyIntegrationSpec extends Specification {
@Autowired
DummyService dummyService
void 'dummy service should exist'() {
expect:
dummyService.getMessage() == DummyConfiguration.MESSAGE
}
}
and this TestApplication class at src/test/groovy/com/example/project/TestApplication.groovy
@SpringBootApplication(scanBasePackages = 'com.example.project.config')
@EnableAutoConfiguration
class TestApplication extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(TestApplication)
}
static void main(String[] args) {
SpringApplication.run(TestApplication, args)
}
}
The two key changes I had to make in order for the TestApplication to start and load the correct context when I moved my TestApplication class from src/main
to src/test
were:
the TestApplication class needed to be added to the ContextConfiguration annotation
the package that my library's Java config files live in needed to be added to the SpringBootApplication scanBasePackages field
The library auto-configuration does follow a similar structure to the one mentioned in the link tom provided.
Your auto-configuration should be automatically picked while your main spring application/test is starting and all beans will be registered in your context. They will be available for auto-wiring and follow your conditions and init order.
As a summary, make sure you have an auto-configuration annotated by @Configuration
class with an @Import
that imports your @Configuration
annotated configuration classes (inside of them you define beans with methods annotated with @Bean
). Also make sure you created a spring.factories
file that include your auto-configuration
class and that you removed the spring boot maven plugin (for the packaging to be right).
Also, make sure your auto-configuration
project is NOT annotated by things like @SpringBootApplication
, @EnableAutoConfiguration
, @ComponentScan
or other spring boot annotations that need to be only in the main spring boot projects (There should be one of them in each stack).
Please also see the article below:
Spring boot is based on a lot of pre-made auto-configuration parent projects. You should already be familiar with spring boot starter projects.
You can easily create your own starter project by doing the following easy steps:
Create some
@Configuration
classes to define default beans. You should use external properties as much as possible to allow customization and try to use auto-configuration helper annotations like@AutoConfigureBefore
,@AutoConfigureAfter
,@ConditionalOnBean
,@ConditionalOnMissingBean
etc. You can find more detailed information on each annotation in the official documentation Condition annotationsPlace an auto-configuration file/files that aggregates all of the
@Configuration
classes.Create a file named
spring.factories
and place it insrc/main/resources/META-INF
.In
spring.factories
, setorg.springframework.boot.autoconfigure.EnableAutoConfiguration
property with comma separated values of your@Configuration
classes:org.springframework.boot.autoconfigure.EnableAutoConfiguration=
com.mycorp.libx.autoconfigure.LibXAutoConfiguration,
com.mycorp.libx.autoconfigure.LibXWebAutoConfiguration Using this method you can create your own auto-configuration classes that will be picked by spring-boot. Spring-boot automatically scan all maven/gradle dependencies for aspring.factories
file, if it finds one, it adds all@Configuration
classes specified in it to its auto-configuration process.
Make sure your auto-configuration
starter project does not contain spring boot maven plugin
because it will package the project as an executable JAR and won't be loaded by the classpath as intended - spring boot will not be able to find your spring.factories
and won't load your configuration