You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot集成Elasticsearch测试抛出Cassandra异常求助

问题分析与调试解决方案

你碰到的核心问题很明确:当测试类PerformanceReportingIntTest继承AbstractElasticSearchTest时,Spring加载完整应用上下文时会尝试初始化Cassandra相关Bean,但你的Elasticsearch测试类并没有启动嵌入式Cassandra,导致DatabaseDescriptor.getNativeTransportPort抛出空指针——而那些继承AbstractCassandraTest的测试能正常运行,正是因为这个抽象类包含了嵌入式Cassandra的启动逻辑。

下面给你几个可行的调试和解决方向:

1. 合并嵌入式服务的启动逻辑(推荐,适合同时需要两者的测试)

Java不支持多继承,所以你可以创建一个新的抽象测试类,把Cassandra和Elasticsearch的启动/停止逻辑整合在一起:

@ActiveProfiles(JHipsterConstants.SPRING_PROFILE_TEST)
public abstract class AbstractCassandraElasticTest extends AbstractCassandraTest {
    private static EmbeddedElastic embeddedElastic;

    @BeforeClass
    public static void startEmbeddedServices() throws Exception {
        // 先启动Cassandra(复用AbstractCassandraTest的逻辑)
        // 假设AbstractCassandraTest有对应的静态启动方法,比如startEmbeddedCassandra()
        AbstractCassandraTest.startEmbeddedCassandra();
        
        // 再启动Elasticsearch
        embeddedElastic = EmbeddedElastic.builder().withElasticVersion("6.6.1")
            .withSetting(PopularProperties.TRANSPORT_TCP_PORT, 9350)
            .withSetting(PopularProperties.CLUSTER_NAME, "my_cluster")
            .withStartTimeout(2, TimeUnit.MINUTES)
            .withIndex("cars", IndexSettings.builder()
                .withType("car", getSystemResourceAsStream())
                .build())
            .build()
            .start();
    }

    private static InputStream getSystemResourceAsStream() throws FileNotFoundException {
        ClassLoader classloader = Thread.currentThread().getContextClassLoader();
        return classloader.getResourceAsStream("config/elasticsearch/car-mapping.json");
    }

    @AfterClass
    public static void stopEmbeddedServices() {
        // 先停止Elasticsearch
        if (embeddedElastic != null) {
            embeddedElastic.stop();
        }
        // 再停止Cassandra(复用AbstractCassandraTest的停止逻辑)
        AbstractCassandraTest.stopEmbeddedCassandra();
    }
}

然后让你的测试类继承这个新的抽象类:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = PrimecastApp.class)
public class PerformanceReportingIntTest extends AbstractCassandraElasticTest {
    @Test
    public void test() {
        // 你的测试逻辑
    }
}

2. 排除Cassandra配置(如果测试不需要Cassandra)

如果这个测试其实不需要和Cassandra交互,你可以直接在@SpringBootTest中排除Cassandra相关的自动配置类,避免Spring尝试初始化Cassandra Bean:

@RunWith(SpringRunner.class)
@SpringBootTest(
    classes = PrimecastApp.class,
    exclude = {CassandraAutoConfiguration.class, CassandraTestConfiguration.class}
)
public class PerformanceReportingIntTest extends AbstractElasticSearchTest {
    @Test
    public void test() {
    }
}

注意:这里要根据你项目中实际的Cassandra配置类调整排除的类名,确保完全禁用Cassandra的自动初始化。

3. 调试验证步骤

  • 先单独运行继承AbstractCassandraTest的现有测试,确认嵌入式Cassandra能正常启动,排除Cassandra本身的问题;
  • 写一个极简测试类,继承AbstractElasticSearchTest并排除Cassandra配置,验证Elasticsearch嵌入式实例能正常启动;
  • 合并逻辑后,检查测试上下文启动时的日志,确认Cassandra和Elasticsearch都成功初始化,没有端口冲突或启动超时;
  • 核对application-test.yml中的Cassandra配置,确保指向的是嵌入式实例的端口(而非外部服务)。

额外注意事项

  • 确保嵌入式Cassandra和Elasticsearch的端口(比如Cassandra的9042,Elasticsearch的9350)不会和本地已运行的服务冲突;
  • 静态初始化方法的执行顺序:父类的@BeforeClass会先执行,所以继承AbstractCassandraTest后,Cassandra会先启动,再启动Elasticsearch,这个顺序是合理的;
  • 资源清理:@AfterClass要确保两个服务都能正常停止,避免残留进程占用端口。

内容的提问来源于stack exchange,提问作者knowledgeseeker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 06:57:45