如何在Jest测试用例中正确Mock ioredis的get与set方法?
解决ioredis在Jest测试中Mock失效的问题
问题核心在于API模块加载时就直接实例化了Redis客户端,若测试中的Mock未在模块加载前生效,API会使用真实的Redis实例而非Mock对象。以下是两种修正后的测试用例方案:
方案一:手动Mock ioredis
const request = require('supertest'); const express = require('express'); const app = express(); // 必须在引入router之前执行Mock,确保router加载时使用Mock的Redis类 jest.mock('ioredis', () => { const mockRedis = jest.fn(); mockRedis.prototype.get = jest.fn(); return mockRedis; }); // 引入router(此时已使用Mock的ioredis) const router = require('./your-router-file-path'); // 替换为你的router实际路径 app.use(router); describe('/qms API 测试', () => { let redisClient; beforeEach(() => { // 重置Mock状态,避免用例间污染 require('ioredis').mockClear(); redisClient = require('ioredis').mock.instances[0]; }); it('应正确返回预设的缓存数据', async () => { // 预设get方法的异步返回值 const mockQmsData = JSON.stringify({ id: 1, content: 'test qms data' }); redisClient.get.mockResolvedValue(mockQmsData); const response = await request(app).get('/qms'); // 断言get方法被正确调用 expect(redisClient.get).toHaveBeenCalledWith('qms'); // 根据API实际返回逻辑添加响应断言,例如: // expect(response.body).toEqual(JSON.parse(mockQmsData)); }); });
关键说明
- 加载顺序:Mock操作必须早于router的引入,确保API模块使用Mock的Redis构造函数。
- Mock类设计:给Mock的Redis原型添加
get方法的Mock函数,让实例能正常调用并返回预设值。 - 状态重置:在
beforeEach中清空Mock调用记录,避免不同测试用例的状态干扰。
方案二:使用ioredis-mock替代真实客户端
const request = require('supertest'); const express = require('express'); const app = express(); // 直接用ioredis-mock替换真实的ioredis jest.mock('ioredis', () => require('ioredis-mock')); const router = require('./your-router-file-path'); app.use(router); describe('/qms API 测试', () => { let redisClient; beforeEach(async () => { redisClient = require('ioredis').mock.instances[0]; // 提前往Mock Redis中存入测试数据 await redisClient.set('qms', JSON.stringify({ id: 2, content: 'mock qms data' })); }); it('应获取到Mock Redis中的数据', async () => { const response = await request(app).get('/qms'); expect(redisClient.get).toHaveBeenCalledWith('qms'); // 根据API响应逻辑添加断言,例如: // expect(response.body).toEqual({ id: 2, content: 'mock qms data' }); }); });
关键说明
- 利用
jest.mock直接替换ioredis的导出为ioredis-mock,API中的Redis实例会自动变为Mock客户端。 - 在
beforeEach中提前存入测试数据,模拟真实Redis的缓存状态,确保API能获取到预期值。
内容的提问来源于stack exchange,提问作者Saurav Thakur
相关产品推荐
相关产品推荐

