如何为这段JS工具函数代码编写正确的Jest单元测试?
问题根因
- 测试代码存在笔误:代码中写入的
u.b = jest.fn()中u变量未定义,实际应该操作导入的utils对象。 - 核心逻辑问题:
utils.js中a函数内部调用的是模块私有函数function b() {},和挂载到exports上的exports.b是两个完全独立的函数。测试中mock的仅为导出的utils.b,无法影响a内部调用的私有函数,因此统计不到调用次数。
修复方案
方案1:调整原utils.js代码(推荐)
该方案从根源修正原代码内部逻辑和导出逻辑不一致的问题,无需额外依赖:
修改后的utils.js:
exports.a = function a(){ // 调用导出的b方法,而非模块私有b exports.b() } // 原私有b方法可直接删除,保留也不影响逻辑 exports.b = function b(){ }
修正后的测试用例:
var utils = require('./utils') test('b called by a', () => { // 使用spyOn mock方法,支持测试完成后恢复原逻辑 const spyB = jest.spyOn(utils, 'b').mockImplementation(() => {}) utils.a() expect(spyB).toHaveBeenCalled() spyB.mockRestore() })
方案2:不改动原业务代码,借助rewire访问私有方法
如果不能修改原utils.js的代码,可以通过rewire包读取替换模块内部的私有方法:
- 安装依赖:
npm install rewire --save-dev - 编写测试用例:
const rewire = require('rewire') const utils = rewire('./utils') test('b called by a', () => { const mockB = jest.fn() // 替换模块内部的私有b函数 utils.__set__('b', mockB) utils.a() expect(mockB).toHaveBeenCalled() })
内容的提问来源于stack exchange,提问作者ishowman
相关产品推荐
相关产品推荐

