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

如何在单元测试前通过TestContainer加载Redis函数?

使用Testcontainers加载Redis自定义Lua函数

你可以通过两种方式在Testcontainers中完成Redis自定义函数的加载,替代原来的Redis CLI管道操作:

方法一:通过Lettuce客户端直接加载(推荐)

利用Lettuce提供的API直接执行FUNCTION LOAD REPLACE命令,和业务代码使用的客户端保持一致,避免环境差异。

示例代码(Java)

import org.testcontainers.containers.GenericContainer;
import org.testcontainers.utility.DockerImageName;
import io.lettuce.core.RedisClient;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.api.sync.RedisCommands;
import java.nio.file.Files;
import java.nio.file.Paths;

public class RedisFunctionTest {
    // 启动Redis容器
    private static final GenericContainer<?> redisContainer = new GenericContainer<>(DockerImageName.parse("redis:latest"))
            .withExposedPorts(6379);

    public static void main(String[] args) throws Exception {
        redisContainer.start();

        // 读取本地Lua脚本文件内容
        String luaScript = new String(Files.readAllBytes(Paths.get("mylib.lua")));

        // 连接到Testcontainers中的Redis实例
        RedisClient redisClient = RedisClient.create(String.format("redis://%s:%d",
                redisContainer.getHost(), redisContainer.getMappedPort(6379)));
        
        try (StatefulRedisConnection<String, String> connection = redisClient.connect()) {
            RedisCommands<String, String> syncCommands = connection.sync();
            // 执行FUNCTION LOAD REPLACE命令,加载脚本
            String functionSha = syncCommands.functionLoadReplace(luaScript);
            System.out.println("加载成功,函数SHA值:" + functionSha);
        } finally {
            redisClient.shutdown();
            redisContainer.stop();
        }
    }
}

方法二:模拟CLI管道操作(通过容器exec命令)

如果想完全复用原有CLI命令的逻辑,可以将Lua脚本复制到容器内,再通过execInContainer执行shell命令完成加载。

示例代码(Java)

import org.testcontainers.containers.GenericContainer;
import org.testcontainers.utility.DockerImageName;
import org.testcontainers.containers.MountableFile;
import org.testcontainers.containers.ExecResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class RedisFunctionCliTest {
    private static final Logger log = LoggerFactory.getLogger(RedisFunctionCliTest.class);
    private static final GenericContainer<?> redisContainer = new GenericContainer<>(DockerImageName.parse("redis:latest"))
            .withExposedPorts(6379)
            // 将本地脚本复制到容器内指定路径
            .withCopyFileToContainer(MountableFile.forHostPath("mylib.lua"), "/tmp/mylib.lua");

    public static void main(String[] args) throws Exception {
        redisContainer.start();

        // 执行shell命令模拟CLI管道操作
        ExecResult result = redisContainer.execInContainer("sh", "-c", "cat /tmp/mylib.lua | redis-cli FUNCTION LOAD REPLACE");
        
        if (result.getExitCode() == 0) {
            System.out.println("脚本加载成功:" + result.getStdout());
        } else {
            System.err.println("脚本加载失败:" + result.getStderr());
        }

        redisContainer.stop();
    }
}

说明

  • 方法一无需依赖容器内的shell环境,更稳定且符合单元测试的代码调用逻辑。
  • 方法二完全复刻原有CLI操作,适合快速迁移原有脚本加载逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 05:07:32