全部学科
NodeJS全栈
nodejs
Python全栈
python
小程序首页
📅 2026-05-18 6 分钟 ✍️ juanwangdev

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覆盖能力
  • 组合测试覆盖各种配置场景

📝 发现内容有误?点击此处直接编辑

← 上一篇 Spring Boot 自定义Starter命名规范
下一篇 → Spring Boot 配置属性绑定
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库