如何使用Jest模拟ES6模块导入?附示例代码
如何用Jest模拟ES6模块导入?
你现在的代码结构是这样的:
store.js
// ../store.js function getData(data) { return data / 3; } export { getData };
myModule.js
// ../myModule.js import { getData } from './store'; function myModule(param) { return getData(param) * 4; } export { myModule };
原测试文件(存在问题)
// ./myModule.test.js import { myModule } from '../myModule'; test('2 x 4 equal 8', () => { expect(getData(6)).toBe(8); });
首先得说下原测试的问题:你直接在测试里调用了getData,但这个函数根本没在测试文件里导入,而且我们测试myModule的核心是验证它的逻辑(调用getData后乘以4),而不是依赖getData的真实实现,所以需要用Jest模拟getData的返回值。
接下来讲具体的模拟方法:
方法一:自动模拟整个模块
Jest提供了jest.mock方法可以快速模拟整个模块,它会自动把模块里的所有导出替换为Jest的mock函数,步骤如下:
修改后的测试文件:
// ./myModule.test.js import { myModule } from '../myModule'; import { getData } from '../store'; // 这行代码会自动模拟../store模块的所有导出 jest.mock('../store'); test('myModule(6) should return 8', () => { // 设置getData模拟返回2(对应真实逻辑里6/3的结果) getData.mockReturnValue(2); // 验证myModule的逻辑:调用getData(6)后乘以4,结果是8 expect(myModule(6)).toBe(8); // 还可以验证getData是否被正确调用了一次,参数是6 expect(getData).toHaveBeenCalledWith(6); });
解释一下:jest.mock('../store')会自动生成mock版本的getData函数,我们可以通过mockReturnValue来控制它的返回值,这样就能完全隔离store.js的真实实现,专注测试myModule的逻辑是否正确。
方法二:自定义模块模拟(工厂函数方式)
如果你需要更精细地控制模拟内容,可以用jest.mock的工厂函数版本,手动指定要模拟的导出:
// ./myModule.test.js import { myModule } from '../myModule'; import { getData } from '../store'; // 用工厂函数自定义模拟内容 jest.mock('../store', () => ({ // 创建一个mock函数,初始可以不指定返回值 getData: jest.fn() })); test('myModule(6) should return 8', () => { // 动态设置返回值 getData.mockReturnValue(2); expect(myModule(6)).toBe(8); expect(getData).toHaveBeenCalledTimes(1); // 验证调用次数 });
如果想直接在模拟时就指定固定返回值,也可以这么写:
jest.mock('../store', () => ({ getData: jest.fn(() => 2) }));
补充:原测试的错误点
你原来的测试里expect(getData(6)).toBe(8)是错误的,因为真实的getData(6)返回的是6/3=2,而你要测试的是myModule的逻辑——它会把getData的返回值乘以4,所以正确的断言应该是expect(myModule(6)).toBe(8)。
内容的提问来源于stack exchange,提问作者Sunrise
相关产品推荐
相关产品推荐

