如何使用Jest fn()?Mock外部getUser函数时赋值报错求助
解决Jest Mock外部getUser函数的问题
首先,你之前写的getUser() = mockGetUser是语法错误——左边是函数调用表达式,不能作为赋值目标,这也是报错的直接原因。要Mock类内部调用的外部getUser函数,得根据这个函数的导入方式来处理,下面分两种常见场景给出解决方案:
场景1:getUser是从某个模块导入的(推荐的模块化写法)
假设你的MyNiceLogin.js里是通过模块化方式引入getUser的,比如:
// MyNiceLogin.js const { getUser } = require('./utils/api'); // CommonJS // 或 ES模块:import { getUser } from './utils/api';
这种情况下,用jest.mock()直接Mock整个依赖模块即可:
const MyNiceLogin = require('../Website/js/MyNiceLogin.js'); // 1. Mock getUser所在的模块,替换getUser为jest mock函数 jest.mock('../Website/js/utils/api', () => ({ // 注意:原getUser是async函数,Mock要返回Promise getUser: jest.fn(() => Promise.resolve('true')) })); describe('Test 1', () => { test('not logged in user on soft login => not relayed to login page', async () => { // 可选:在测试前重置mock或设置自定义返回值 const { getUser } = require('../Website/js/utils/api'); getUser.mockResolvedValue('true'); // 注意:构造函数里调用了async私有方法,需要等待异步逻辑完成 new MyNiceLogin.MyNiceLogin(true); await new Promise(resolve => setImmediate(resolve)); // 等待微任务队列执行完毕 expect(sessionStorage.getItem).toHaveBeenCalledTimes(1); // 可选:验证getUser是否被调用 expect(getUser).toHaveBeenCalled(); }); });
场景2:getUser是全局变量(不推荐但需兼容的情况)
如果getUser是挂载在全局对象(比如window或global)上的,直接替换全局属性即可:
const MyNiceLogin = require('../Website/js/MyNiceLogin.js'); describe('Test 1', () => { // 测试前初始化mock beforeEach(() => { global.getUser = jest.fn(() => Promise.resolve('true')); }); // 测试后清理全局变量 afterEach(() => { delete global.getUser; }); test('not logged in user on soft login => not relayed to login page', async () => { new MyNiceLogin.MyNiceLogin(true); await new Promise(resolve => setImmediate(resolve)); // 等待异步逻辑完成 expect(sessionStorage.getItem).toHaveBeenCalledTimes(1); expect(global.getUser).toHaveBeenCalled(); }); });
关键注意事项
- 异步处理:你的
#getUser是async方法,但构造函数是同步的——构造函数里调用async方法不会等待它执行完成,所以测试时必须用await new Promise(...)这类方式,等待异步逻辑跑完再断言。 - Mock返回值类型:原
getUser是async函数,Mock函数必须返回Promise(用mockResolvedValue或直接返回Promise.resolve(...)),否则await getUser(...)会抛出错误。
内容的提问来源于stack exchange,提问作者HOK
相关产品推荐
相关产品推荐

