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

Redis-Mock无法连接及命令返回undefined问题求助

解决Jest测试Redis v4封装类时redis-mock不兼容的问题

问题回顾

使用redis@4.5.0封装Redis客户端,通过jest.mock引入redis-mock@0.56.3做单元测试时,出现两个核心问题:

  1. 调用redisClient.connect()时报错:TypeError: this._redisClient.connect is not a function
  2. 注释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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 00:47:47