Redis-Mock无法连接及命令返回undefined问题求助
解决Jest测试Redis v4封装类时redis-mock不兼容的问题
问题回顾
使用redis@4.5.0封装Redis客户端,通过jest.mock引入redis-mock@0.56.3做单元测试时,出现两个核心问题:
- 调用
redisClient.connect()时报错:TypeError: this._redisClient.connect is not a function - 注释
connect/disconnect后,执行Redis命令(如SADD/SMEMBERS)返回undefined
核心原因
redis-mock@0.56.3仅支持Redis v3的API规范,而你的代码使用的是Redis v4的全新API:
- Redis v4新增了显式的
connect()/disconnect()方法用于管理连接 - Redis v4的命令全部改为Promise化的小驼峰命名(如
sAdd()而非SADD) - redis-mock仍基于回调风格实现命令,直接
await会返回undefined
解决方案
方案1:手动Mock Redis v4核心API(推荐,无额外依赖)
不需要依赖第三方mock库,直接在Jest中模拟redis模块的关键方法,适配你的封装类需求:
修改jest.setup.redis-mock.js:
jest.mock('redis', () => { // 模拟Redis客户端实例,按需添加你用到的命令 const mockClient = { connect: jest.fn().mockResolvedValue(), disconnect: jest.fn().mockResolvedValue(), sAdd: jest.fn().mockResolvedValue(1), sMembers: jest.fn().mockResolvedValue(['Hello']), // 其他你需要的Redis命令,比如get/set等 }; return { createClient: jest.fn().mockReturnValue(mockClient), RedisClientType: jest.fn(), // 模拟类型导出 }; });
这种方式完全可控,能精准匹配你的封装类调用逻辑,避免依赖兼容性问题。
方案2:使用支持Redis v4的Mock库
安装专门适配Redis v4的@redis/mock库:
npm install @redis/mock --save-dev
修改jest.setup.redis-mock.js:
jest.mock('redis', () => jest.requireActual('@redis/mock'));
该库实现了Redis v4的大部分API,包括connect()/disconnect()和Promise化命令,能直接适配你的现有封装类代码。
方案3:降级Redis到v3版本
如果允许调整项目依赖,将redis降级到v3.x版本,此时redis-mock的API能完全匹配:
npm install redis@3.1.2 --save
同时修改封装类适配Redis v3的API(无需显式connect,命令需调用.promise()):
import { createClient, RedisClient } from 'redis'; class Redis { private _redisClient: RedisClient; constructor(private _configuration: IRedisConfiguration) { this._redisClient = createClient({ url: this._configuration.url, username: this._configuration.userName, password: this._configuration.password }); } public async init(): Promise<void> { // Redis v3无需显式connect,客户端自动建立连接 } public async destroy(): Promise<void> { this._redisClient.quit(); } public async addToSet(key: string, value: string): Promise<number> { // v3命令需调用.promise()转为Promise return this._redisClient.sadd(key, value).promise(); } }
关于编辑1/2的补充说明
redis-mock的命令是回调风格实现,你直接await client.sadd(...)时,由于方法本身不返回Promise,所以会得到undefined。如果坚持用redis-mock,需要手动封装Promise:
// 不推荐,仅作演示 const saddPromise = (key, value) => new Promise((resolve) => { client.sadd(key, value, (err, result) => resolve(result)); }); await saddPromise('test', 'test');
但这种方式完全不符合Redis v4的用法,因此不建议采用。
内容的提问来源于stack exchange,提问作者jereczq22
相关产品推荐
相关产品推荐

