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

Spring Webflux集成测试:WebTestClient注入与Redis启动顺序问题

解决方案:Spring Webflux集成测试的WebTestClient注入与嵌入式Redis加载顺序问题

我之前也碰到过类似的坑,给你两个方向的解决方案,应该能搞定你的问题:


方案一:无需启动Web环境即可注入WebTestClient

默认情况下,@SpringBootTest的webEnvironment是MOCK模式,这时候Spring不会自动创建WebTestClient的Bean。你只需要加上@AutoConfigureWebTestClient注解,就能触发WebTestClient的自动配置:

@SpringBootTest
@ActiveProfiles("test")
@AutoConfigureWebTestClient // 关键注解,自动配置WebTestClient
class FooControllerIT {

    @Autowired
    private WebTestClient webTestClient;

    // 测试方法示例
    @Test
    void testFooEndpoint() {
        webTestClient.get().uri("/foo")
                .exchange()
                .expectStatus().isOk();
    }
}

如果不想用自动配置,也可以手动绑定到应用上下文构建WebTestClient:

@SpringBootTest
@ActiveProfiles("test")
class FooControllerIT {

    private WebTestClient webTestClient;

    @Autowired
    public void setUp(ApplicationContext context) {
        // 手动绑定上下文,创建WebTestClient
        webTestClient = WebTestClient.bindToApplicationContext(context).build();
    }

    // 测试方法...
}

方案二:让嵌入式Redis配置优先于Redisson加载

如果还是需要启动Web环境,或者想彻底解决Redisson连接问题,核心是确保嵌入式Redis的配置在RedissonAutoConfiguration之前加载,让Redis服务器先启动再初始化Redisson客户端。

方法1:使用@AutoConfigureBefore指定加载顺序

修改你的EmbeddedRedisConfiguration,加上@AutoConfigureBefore(RedissonAutoConfiguration.class),强制Spring先加载嵌入式Redis配置:

@Profile("test")
@Configuration
@AutoConfigureBefore(RedissonAutoConfiguration.class) // 确保此配置在Redisson之前加载
public class EmbeddedRedisConfiguration {

    private RedisServer redisServer;

    @Value("${spring.redis.port:6379}")
    private int redisPort;

    @PostConstruct
    public void startEmbeddedRedis() {
        // 启动嵌入式Redis服务器
        redisServer = new RedisServer(redisPort);
        redisServer.start();
    }

    @PreDestroy
    public void stopEmbeddedRedis() {
        if (redisServer != null) {
            redisServer.stop();
        }
    }

    // 配置Redis连接工厂,供Spring Data Redis使用
    @Bean
    public RedisConnectionFactory redisConnectionFactory() {
        return new LettuceConnectionFactory("localhost", redisPort);
    }
}

方法2:动态设置Redis端口到环境变量

如果担心端口冲突,可以让嵌入式Redis随机启动端口,然后把实际端口注入到环境变量,让Redisson自动读取:

@Profile("test")
@Configuration
public class EmbeddedRedisConfiguration {

    private RedisServer redisServer;

    @PostConstruct
    public void startEmbeddedRedis() {
        // 随机端口启动Redis
        redisServer = RedisServer.builder().randomPort().build();
        redisServer.start();
        // 获取实际启动的端口
        int actualPort = redisServer.getPort();
        // 设置到环境变量,Redisson会读取spring.redis.port配置
        System.setProperty("spring.redis.port", String.valueOf(actualPort));
    }

    @PreDestroy
    public void stopEmbeddedRedis() {
        if (redisServer != null) {
            redisServer.stop();
        }
    }
}

方法3:用@DependsOn强制依赖顺序

如果你的Redisson配置是自定义Bean,可以给Redisson的Bean加上@DependsOn("redisServer"),确保Redis服务器Bean先初始化:

@Bean
@DependsOn("redisServer") // 依赖嵌入式Redis的Bean
public RedissonClient redissonClient() {
    Config config = new Config();
    config.useSingleServer().setAddress("redis://localhost:" + redisPort);
    return Redisson.create(config);
}

推荐优先尝试方案一 + 方法1的组合:用@AutoConfigureWebTestClient避免启动真实Web环境,同时用@AutoConfigureBefore确保Redis先启动,这样两个问题都能解决。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:51:24