如何用Jest模拟ESM模块依赖函数实现一致测试?
问题:Jest测试ESM模块时模拟依赖函数以保证一致结果
我有两个使用JavaScript编写的ESM模块:
randomNumber.js
export function generateRandomNumber() { return a random number }
selectElement.js
import { generateRandomNumber } from './randomNumber.js' export function selectRandomElement() { const myArray = ['a', 'b', 'c', 'd'] const randomNumber = generateRandomNumber() return myArray[randomNumber] }
希望使用Jest测试selectElement.js,要求不重构原有模块结构,仅修改测试文件,模拟randomNumber.js中的generateRandomNumber函数,让每次调用selectRandomElement都返回'a'。初始测试代码如下:
tests/selectElement.test.js
import { selectRandomElement } from '../selectElement.js' const generateRandomNumber = () => 0 // 计划用作mock的函数 test('check we get the letter a', () => { expect(selectRandomElement()).toBe('a') expect(selectRandomElement()).toBe('a') expect(selectRandomElement()).toBe('a') expect(selectRandomElement()).toBe('a') });
解决方案
可以实现,直接在测试文件中使用Jest的jest.mock方法拦截目标模块的导入,替换为自定义的模拟实现即可,修改后的测试代码如下:
import { selectRandomElement } from '../selectElement.js' // 模拟randomNumber模块,替换generateRandomNumber为固定返回0的函数 jest.mock('../randomNumber.js', () => ({ generateRandomNumber: () => 0 })) test('check we get the letter a', () => { expect(selectRandomElement()).toBe('a') expect(selectRandomElement()).toBe('a') expect(selectRandomElement()).toBe('a') expect(selectRandomElement()).toBe('a') });
关键说明:
jest.mock会自动覆盖对../randomNumber.js的导入,所有依赖该模块的代码都会使用你定义的模拟版本- 模拟的
generateRandomNumber固定返回0,对应数组的第一个元素'a',确保每次调用selectRandomElement结果完全一致 - 该方案完全适配ESM环境,无需修改原有模块的结构或导入逻辑
内容的提问来源于stack exchange,提问作者hojkoff
相关产品推荐
相关产品推荐

