@SpringBootTest 按需加载轻量、隔离、可复用的测试上下文,核心在于控制加载范围和避免冗余初始化;应根据测试目标选择合适注解:集成场景用 @SpringBootTest,单 Service 逻辑用 Mockito,Web 层契约用 @WebMvcTest,JPA Repository 用 @DataJpaTest。

@SpringBootTest 不是“启动整个应用”,而是按需加载一个轻量、隔离、可复用的 Spring 测试上下文。关键不在“拉起”,而在“控制加载范围”和“避免冗余初始化”。
明确测试目标,选对上下文粒度
不是所有测试都需要完整上下文。优先考虑是否真的需要 @SpringBootTest:
- 验证 Bean 间依赖注入、自动配置生效、事务行为、Web 端点连通性等集成场景 → 用 @SpringBootTest
- 只测单个 Service 逻辑,且不依赖其他 Spring Bean → 直接 new 实例或用 @ExtendWith(MockitoExtension.class),无需 Spring 上下文
- 只测 Controller 层契约(JSON 输入/输出)→ 用 @WebMvcTest,它只加载 Web 层相关 Bean,不启动数据源、Service 等
- 只测 JPA Repository → 用 @DataJpaTest,自动配好内存数据库和 EntityManager,跳过 Service 和 Web 层
缩小上下文加载范围,加速启动
默认情况下 @SpringBootTest 会扫描整个 classpath,代价高。可通过以下方式收敛:
- 使用 @SpringBootTest(classes = {OrderService.class, PaymentConfig.class}) 显式指定需加载的配置类或组件,跳过自动扫描
- 搭配 @Import(TestConfiguration.class) 引入最小化测试专用配置,避免加载生产 profile 中的 Kafka、Redis、定时任务等重型 Bean
- 禁用无用自动配置:@SpringBootTest(exclude = {DataSourceAutoConfiguration.class, RedisAutoConfiguration.class})
- 设置 spring.test.mock.env=false(在 test/resources/application.properties 中)防止环境变量干扰;测试中尽量用 @TestConfiguration 替代全局配置
复用上下文,避免重复加载
Spring Test 默认对相同配置参数的测试类复用同一个 ApplicationContext,但容易被无意破坏:
立即学习“Java免费学习笔记(深入)”;
- 确保测试类的 @SpringBootTest 参数一致(如 webEnvironment、classes、exclude 等),否则会创建新上下文
- 避免在测试方法里修改共享 Bean 的状态(如 static 字段、单例 Bean 的可变字段),否则污染后续测试
- 慎用 @DirtiesContext:它强制刷新上下文,适合极少数需重置状态的场景,但会显著拖慢执行速度
- 若需多组隔离上下文(如不同数据库连接),可用 @ContextConfiguration + 自定义 ApplicationContextInitializer 分离环境
配合 Web 环境做端到端验证
需要真正发起 HTTP 请求时,推荐用 RANDOM_PORT 而非 MOCK:
- @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) 启动真实内嵌服务器(Tomcat/Jetty),端口随机分配,适合验证完整请求链路
- 通过 @LocalServerPort 注入实际端口,用 RestTemplate 或 WebClient 发起调用
- 避免使用 webEnvironment = WebEnvironment.MOCK 做“伪集成”——它绕过 Servlet 容器,无法测过滤器、跨域、SSL、路径匹配等真实行为


















