Spring Boot 自定义Starter测试
自定义Starter需编写测试验证自动配置正确生效。
测试依赖
XML
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
ApplicationContextRunner
Java
class MyAutoConfigurationTest {
private final ApplicationContextRunner contextRunner =
new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(MyAutoConfiguration.class));
@Test
void defaultServiceCreated() {
contextRunner.run(context -> {
assertThat(context).hasSingleBean(MyService.class);
assertThat(context.getBean(MyService.class).getName())
.isEqualTo("default");
});
}
@Test
void serviceNotCreatedWhenDisabled() {
contextRunner
.withPropertyValues("my.service.enabled=false")
.run(context -> {
assertThat(context).doesNotHaveBean(MyService.class);
});
}
}
条件注解测试
测试@ConditionalOnClass
Java
@Test
void serviceCreatedWhenClassPresent() {
contextRunner
.withClassLoader(new FilteredClassLoader(MyService.class))
.run(context -> {
assertThat(context).doesNotHaveBean(MyService.class);
});
}
@Test
void serviceNotCreatedWhenClassMissing() {
contextRunner
.withClassLoader(new FilteredClassLoader())
.run(context -> {
assertThat(context).doesNotHaveBean(MyService.class);
});
}
测试@ConditionalOnBean
Java
@Test
void serviceCreatedWhenDependencyBeanPresent() {
contextRunner
.withBean(DataSource.class, () -> new MockDataSource())
.run(context -> {
assertThat(context).hasSingleBean(MyService.class);
});
}
@Test
void serviceNotCreatedWhenDependencyBeanMissing() {
contextRunner.run(context -> {
assertThat(context).doesNotHaveBean(MyService.class);
});
}
配置属性测试
Java
class MyPropertiesTest {
private final ApplicationContextRunner contextRunner =
new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(MyAutoConfiguration.class))
.withUserConfiguration(MyPropertiesTestConfiguration.class);
@Test
void propertiesBoundCorrectly() {
contextRunner
.withPropertyValues(
"my.service.name=test-name",
"my.service.timeout=5000"
)
.run(context -> {
MyProperties properties = context.getBean(MyProperties.class);
assertThat(properties.getName()).isEqualTo("test-name");
assertThat(properties.getTimeout()).isEqualTo(5000);
});
}
@Test
void defaultValuesApplied() {
contextRunner.run(context -> {
MyProperties properties = context.getBean(MyProperties.class);
assertThat(properties.getName()).isEqualTo("default");
assertThat(properties.getTimeout()).isEqualTo(3000);
});
}
}
Web环境测试
Java
private final WebApplicationContextRunner webContextRunner =
new WebApplicationContextRunner(
WebApplicationContextRunner.WebType.SERVLET)
.withConfiguration(AutoConfigurations.of(MyWebAutoConfiguration.class));
@Test
void webConfigurationCreatedInWebEnvironment() {
webContextRunner.run(context -> {
assertThat(context).hasSingleBean(MyWebConfiguration.class);
});
}
测试用户覆盖
Java
@Test
void userBeanOverridesDefaultBean() {
contextRunner
.withBean(MyService.class, () -> new CustomMyService())
.run(context -> {
assertThat(context).hasSingleBean(MyService.class);
assertThat(context.getBean(MyService.class))
.isInstanceOf(CustomMyService.class);
});
}
自动配置报告验证
Java
@Test
void autoConfigurationReportAvailable() {
contextRunner
.withPropertyValues("debug=true")
.run(context -> {
ConditionEvaluationReport report =
context.getBean(ConditionEvaluationReport.class);
assertThat(report.getConditionAndOutcomesBySource())
.containsKey(MyAutoConfiguration.class.getName());
});
}
集成测试示例
Java
@SpringBootTest
@EnableAutoConfiguration
@Import(MyAutoConfiguration.class)
class MyAutoConfigurationIntegrationTest {
@Autowired(required = false)
private MyService myService;
@Test
void serviceAutoConfigured() {
assertThat(myService).isNotNull();
}
}
测试最佳实践
| 实践 | 说明 |
|---|---|
| 使用ApplicationContextRunner | 独立控制测试上下文 |
| 测试默认行为 | 验证开箱即用 |
| 测试条件注解 | 确认生效条件正确 |
| 测试用户覆盖 | 确认@ConditionalOnMissingBean工作 |
| 测试配置属性 | 验证绑定正确 |
| 测试Bean存在/不存在 | 核心验证点 |
要点总结
- ApplicationContextRunner控制测试上下文配置
- withPropertyValues设置配置属性
- FilteredClassLoader模拟类不存在
- 验证条件注解生效场景
- 测试用户自定义Bean覆盖能力
- 组合测试覆盖各种配置场景
📝 发现内容有误?点击此处直接编辑