Jest测试调用getFY未触发同文件FiscalYear模拟构造函数如何解决?
问题根因
你遇到的问题本质是同一模块内的函数调用指向模块内部作用域的变量,而非导出对象的属性。你用jest.mock修改的只是模块对外导出的FiscalYear属性,模块内部getFY调用的还是作用域里原本的FiscalYear类,所以模拟不会生效。
修复方案
方案一:最小改动适配(无需调整文件结构)
修改FiscalYear.jsx中getFY的调用指向,让它调用模块导出的FiscalYear即可:
export function getFY(offset) { // 原有业务逻辑不变 // 把原来的 new FiscalYear(fy) 改成调用导出对象上的FiscalYear return new exports.FiscalYear(fy); }
改完后你现有的测试代码不需要调整,直接运行即可通过。
方案二:模块拆分(更符合可测试性规范)
如果不想修改业务代码的调用逻辑,可以把FiscalYear类单独抽离到独立文件,让getFY通过导入的方式引用类,这样mock就会自然生效:
- 新建
FiscalYearClass.js保存类定义:
// FiscalYearClass.js export class FiscalYear { constructor(fy) { //does stuff } // other functionality }
- 修改原FiscalYear.jsx逻辑,导入抽离的类:
// FiscalYear.jsx import { FiscalYear } from './FiscalYearClass'; export { FiscalYear }; export function getFY(offset) { // 原有逻辑不变 return new FiscalYear(fy); }
- 调整测试代码,mock抽离的类文件:
import { FiscalYear } from './FiscalYearClass'; import { getFY } from '../FiscalYear'; jest.mock('./FiscalYearClass', () => ({ FiscalYear: jest.fn().mockImplementation((a) => {}) })); test("getFY", () => { getFY(2); expect(FiscalYear).toHaveBeenCalled(); });
设计合理性说明
将类和强关联的工具函数放在同一个文件不属于不良设计,只要这些代码属于同一业务域、内聚性高,放在一起反而更便于维护。如果你的项目没有特别强的文件拆分规范,这种写法是完全可接受的。唯一的缺点就是同一模块内的调用mock成本略高,如果你需要频繁做这类mock,拆分模块会更方便。
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

