Jest环境下如何使用MockDao类模拟DaoClass的实例化过程
问题排查与解决方案
核心错误原因
- 模拟路径不匹配:原代码导入DaoClass的路径是
../db/some-db-dao,你编写的模拟路径是../db/db-dao,路径完全不一致导致模拟未生效,真实DaoClass接收到无效的container参数就会触发属性读取报错。 - container模拟不符合预期:你用
jest.mock('../db/some-config', jest.fn())模拟后,整个模块被替换为空函数,具名导出的container会变成undefined,传入DaoClass构造函数后,构造函数读取其属性时就会触发"Cannot read property xxx of undefined"报错。 - 模块导入顺序错误:你的业务模块中
dao = new DaoClass(container)是顶层代码,会在模块导入时立刻执行,如果jest.mock调用写在导入业务模块之后,模拟还未生效就已经执行了真实实例化逻辑。
正确实现代码
第一步:修正container的模拟
需要让模拟后的模块正确导出container对象,示例如下:
jest.mock('../db/some-config', () => ({ container: { // 此处填入DaoClass构造逻辑需要用到的container属性,无特殊要求可留空对象 } }));
第二步:修正DaoClass的模拟
保证模拟路径和原导入路径完全一致,按导出类型配置模拟逻辑:
// 先导入你自己实现的MockDao import MockDao from './你的MockDao文件路径'; // 默认导出类的模拟写法(适配开启esModuleInterop的场景) jest.mock('../db/some-db-dao', () => { return jest.fn().mockImplementation(() => { return new MockDao(); }); });
如果你未开启
esModuleInterop或者用TS编译的默认导出,需要显式指定default属性:jest.mock('../db/some-db-dao', () => ({ default: jest.fn().mockImplementation(() => new MockDao()) }));
第三步:保证模拟执行顺序
所有jest.mock调用必须放在导入业务模块的代码之前,完整测试文件结构示例:
// 所有模拟逻辑写在文件最顶部 jest.mock('../db/some-config', () => ({ container: {} })); import MockDao from './你的MockDao文件路径'; jest.mock('../db/some-db-dao', () => { return jest.fn().mockImplementation(() => new MockDao()); }); // 模拟全部注册完成后,再导入要测试的业务模块 import { getAllThings, getThingById } from './你的业务模块路径'; // 后续编写测试用例即可 test('getAllThings返回预期数据', () => { // 测试逻辑 });
内容的提问来源于stack exchange,提问作者joshft91
相关产品推荐
相关产品推荐

