Jest模拟loginCognito函数返回undefined问题求助
问题说明
我在src/utils/calls/aws.js中封装了AWS Cognito认证逻辑的loginCognito函数,该函数返回Promise。在LoginPage组件中调用该函数可正常运行,但使用Jest编写测试用例时,尝试了mockReturnValue、mockResolvedValue等多种模拟方式,组件中调用后始终返回undefined。即使将原函数简化为直接返回字符串,模拟后调用仍返回undefined,需要彻底绕过原AWS函数实现并解决该问题。
原函数代码
export const loginCognito = (cognitoUser, authenticationDetails) => { return new Promise((resolve, reject) => { cognitoUser.authenticateUser(authenticationDetails, { onSuccess: resolve, onFailure: reject, newPasswordRequired: resolve, }); }); };
测试中尝试的mock方式
// loginCognito: jest.fn().mockReturnValue(Promise.resolve({accessToken: "an.access.token"})) // loginCognito: jest.fn(() => Promise.resolve(promisedResult)) // loginCognito: jest.fn(() => promisedResult) loginCognito: jest.fn().mockResolvedValue(promisedResult)
简化测试的代码
简化后的原函数
export const loginCognito = () => { return "ciao" }
简化测试的mock代码
jest.mock("../../../utils/calls/aws.js", () => ({ loginCognito: jest.fn().mockReturnValue("addio") }));
解决方案
导致mock后返回undefined的核心原因通常是ES模块导出的识别问题,或者mock路径/时机错误,以下是针对性解决步骤:
确保mock路径与组件导入路径完全一致
检查测试文件中jest.mock的路径,必须和LoginPage组件中导入loginCognito时的相对路径完全匹配,路径错误会导致mock不生效,组件仍调用原函数(或未正确mock的函数)。添加ES模块标识
__esModule: true
由于原文件使用ES模块的export语法,Jest在mock时需要明确标识这是ES模块,否则无法正确绑定导出的函数。修改mock代码如下:jest.mock("../../../utils/calls/aws.js", () => ({ __esModule: true, // 必须添加这一行 loginCognito: jest.fn().mockResolvedValue({ accessToken: "an.access.token" }) }));确保mock在组件导入前执行
Jest会自动将jest.mock提升到文件顶部执行,但如果测试文件中存在动态导入或其他异步逻辑,需确保组件导入(如import LoginPage from '../LoginPage')在mock之后。在测试用例中验证mock函数
可以直接调用mock后的函数,验证其返回值是否符合预期,确认mock生效:import { loginCognito } from '../../../utils/calls/aws.js'; test('mock函数返回正确值', async () => { const result = await loginCognito(); expect(result).toEqual({ accessToken: "an.access.token" }); expect(loginCognito).toHaveBeenCalled(); });
内容的提问来源于stack exchange,提问作者sineverba

