Jest如何仅mock knex.fn.now()并保留knex其余原有实现
针对Knex.fn.now()的Jest局部Mock方案
完全可以实现,不需要全量mock整个knex模块,只需要通过Jest的spyOn方法定向劫持knex.fn.now()方法即可,其余knex功能会完全保留原生实现,不会影响测试有效性。
实现逻辑
通过jest.spyOn只针对knex实例下的fn.now方法做替换,不会改动knex的其他核心逻辑,也不需要修改业务代码。
示例代码
// 导入业务代码中实际初始化完成的knex实例,不要直接导入knex npm包 const knex = require('./path/to/your/knex/init/config'); describe('你的测试分组', () => { let nowSpy; // 固定的测试用时间,可根据需要调整格式,适配你的数据库时间类型 const MOCK_CURRENT_TIME = '2024-05-20 12:00:00'; beforeEach(() => { // 劫持knex.fn.now方法,替换为返回固定时间 // 如果需要和原生knex.fn.now()返回同类型的SQL表达式,可以改成如下写法: // nowSpy = jest.spyOn(knex.fn, 'now').mockReturnValue(knex.raw(`'${MOCK_CURRENT_TIME}'`)); nowSpy = jest.spyOn(knex.fn, 'now').mockReturnValue(MOCK_CURRENT_TIME); }); afterEach(() => { // 恢复原方法,避免spy泄漏到其他测试用例 nowSpy.mockRestore(); }); test('你的测试用例', async () => { // 这里执行业务代码,所有调用knex.fn.now()的位置都会返回固定的MOCK_CURRENT_TIME // 其余knex的查询、事务等功能完全走原生实现 }); });
注意事项
- 如果你的项目中存在多个独立初始化的knex实例,必须确保spy的是业务代码实际调用的那个实例
- 如果业务代码中
knex.fn.now()的返回值需要作为SQL表达式使用,优先选择返回knex.raw包裹的固定时间,避免类型不匹配报错 - TypeScript项目如果出现类型报错,可以在spy后添加
as jest.Mock做临时类型兼容
内容的提问来源于stack exchange,提问作者maxorcist
相关产品推荐
相关产品推荐

