如何在单元测试前通过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
相关产品推荐
相关产品推荐

