如何将自定义CassandraConfig配置类排除出Spring测试上下文?
错误原因分析
- 第一个连接异常:Spring上下文加载时会实例化Cassandra配置类里的CqlSession Bean,尝试连接配置的Cassandra节点,你本地/测试环境没有可用的Cassandra服务,所以连接被拒绝报错。
- 第二个排除配置失败异常:
@EnableAutoConfiguration(exclude)只能排除Spring Boot官方提供的自动配置类,你自己编写的普通@Configuration类是通过包扫描注册到上下文的,不属于自动配置范畴,所以会提示不是自动配置类无法排除。
解决方案
分两种场景选择适配方案:
场景1:测试不需要使用Cassandra(仅测上下文加载、业务逻辑不涉及Cassandra)
推荐以下3种解决方案,灵活度从高到低:
- 方案1:给自定义配置类加条件控制(最佳实践)
给你的CassandraConfig类加上@ConditionalOnProperty注解,通过配置开关控制是否加载:
@Configuration @EnableCassandraRepositories(basePackages = { BASE_PACKAGE }) // 默认开启,配置cassandra.enabled=false时不加载该配置 @ConditionalOnProperty(name = "cassandra.enabled", havingValue = "true", matchIfMissing = true) public class CassandraConfig { // 原有代码不变 }
然后在测试配置文件(src/test/resources/application.properties)里添加配置关闭即可:
cassandra.enabled=false
这种方式不侵入测试代码,后续所有不需要Cassandra的测试都自动生效,生产环境也可以通过这个配置灵活开关。
- 方案2:测试类排除自定义配置类
在测试类上通过包扫描过滤器直接排除CassandraConfig,避免被加载到上下文:
@SpringBootTest @ComponentScan(excludeFilters = @ComponentScan.Filter( type = FilterType.ASSIGNABLE_TYPE, classes = CassandraConfig.class )) class ApplicationTest { @Test void contextLoads() { } }
- 方案3:使用切片测试代替全上下文加载
如果你的测试只需要验证Web层、Service层等特定模块的逻辑,不要用@SpringBootTest加载全上下文,改用@WebMvcTest、@ServiceTest等切片注解,只会加载指定范围的Bean,不会触发Cassandra相关配置的加载。
场景2:测试需要使用Cassandra(集成测试场景)
推荐使用Testcontainers启动临时Cassandra容器作为测试数据源,不需要本地安装Cassandra,也不会影响开发/生产环境数据:
- 引入Testcontainers Cassandra依赖
- 测试类配置启动临时Cassandra容器,自动将连接配置注入上下文
@SpringBootTest @Testcontainers class ApplicationTest { @Container private static final CassandraContainer cassandra = new CassandraContainer("cassandra:4.1") .withInitScript("init-cassandra.cql"); // 可选,初始化表结构的脚本 @DynamicPropertySource static void setCassandraProperties(DynamicPropertyRegistry registry) { registry.add("spring.data.cassandra.contact-points", cassandra::getContactPoint); registry.add("spring.data.cassandra.port", cassandra::getMappedPort); registry.add("spring.data.cassandra.local-datacenter", cassandra::getLocalDatacenter); registry.add("spring.data.cassandra.keyspace-name", () -> "test_keyspace"); } @Test void contextLoads() { } }
如果不使用Testcontainers,也可以检查本地Cassandra服务是否启动、测试配置里的连接地址、端口、数据中心名称是否和实际Cassandra配置一致。
内容的提问来源于stack exchange,提问作者Alexey
相关产品推荐
相关产品推荐

