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

Spring Boot微服务网关JUnit测试报错,求修复方案

解决Spring Boot网关JUnit测试的StackOverflowError问题

问题根源

  1. 重复启动上下文:你的mainMethodTest直接调用了GatewayServiceApplication.main(),而@SpringBootTest注解本身已经会启动Spring应用上下文,这会导致重复初始化上下文,触发循环逻辑从而抛出StackOverflowError。
  2. 依赖真实Eureka服务:网关需要Eureka Server才能正常启动,测试环境下没有Eureka服务时,Spring会不断重试注册,也可能加剧栈溢出问题。

修复步骤

1. 移除重复启动上下文的测试方法

删掉mainMethodTest,因为@SpringBootTest已经完成了应用启动的验证,不需要额外调用main方法。

2. 测试环境禁用Eureka客户端或模拟Eureka

有两种方案可选:

方案一:禁用DiscoveryClient自动配置

在测试类上添加@SpringBootTest的properties参数,直接禁用Eureka客户端的自动配置,让网关在测试时不依赖Eureka:

@SpringBootTest(properties = {
    "spring.cloud.discovery.enabled=false",
    "spring.cloud.gateway.discovery.locator.enabled=false"
})
class GatewayServiceApplicationTest {

    @Autowired
    private ApplicationContext context;

    @DisplayName("应用上下文加载正常")
    @Test
    void contextLoads() {
        assertThat(context).isNotNull();
    }

    @DisplayName("网关服务Bean已初始化")
    @Test
    void gatewayServiceIsEnabledAndRunning() {
        assertThat(context.getBean(GatewayServiceApplication.class)).isNotNull();
    }
}
方案二:使用测试容器模拟Eureka Server(适合需要验证服务发现逻辑的场景)

如果需要测试完整的服务发现功能,可以用Testcontainers启动一个Eureka容器,示例如下:
首先添加Testcontainers依赖(Maven):

<dependency>
    <groupId>org.testcontainers</groupId>
    <artifactId>testcontainers</artifactId>
    <version>1.19.3</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.testcontainers</groupId>
    <artifactId>junit-jupiter</artifactId>
    <version>1.19.3</version>
    <scope>test</scope>
</dependency>

然后修改测试类:

@SpringBootTest
@Testcontainers
class GatewayServiceApplicationTest {

    @Container
    private static GenericContainer<?> eurekaContainer = new GenericContainer<>("springcloud/eureka:1.0.0")
            .withExposedPorts(8761);

    @Autowired
    private ApplicationContext context;

    @BeforeAll
    static void setupEureka() {
        System.setProperty("spring.cloud.discovery.client.simple.local.uri", 
            "http://" + eurekaContainer.getHost() + ":" + eurekaContainer.getMappedPort(8761));
    }

    @DisplayName("应用上下文加载正常")
    @Test
    void contextLoads() {
        assertThat(context).isNotNull();
    }

    @DisplayName("网关服务Bean已初始化")
    @Test
    void gatewayServiceIsEnabledAndRunning() {
        assertThat(context.getBean(GatewayServiceApplication.class)).isNotNull();
    }
}

关键说明

  • 方案一适合快速验证应用启动逻辑,不需要依赖外部服务;
  • 方案二适合需要测试网关与Eureka交互的场景,更贴近生产环境;
  • 永远不要在@SpringBootTest的测试方法中再次调用main(),这会导致上下文重复初始化,引发栈溢出或其他异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 14:25:27