Jest测试返回Promise的导入函数时,Mock函数未被调用如何修复?
问题修复:Jest Mock未被调用的问题
问题场景
有一个简单的Lambda函数需要编写测试以满足覆盖率要求,函数代码如下:
import { lambdaPromise } from '@helpers'; export const main = async event => lambdaPromise(event, findUsers);
lambdaPromise()函数返回一个Promise,尝试通过Mock验证它是否被调用,但测试中mockLambdaPromise从未触发,测试代码如下:
import { main, findUsers } from '../src/lambdas/user/findUsers'; import { lambdaPromise } from '@helpers'; const mockEvent = { arguments: { userDataQuery: { email: 'johndoe@whatever.com' } } }; const mockLambdaPromise = jest.fn(); jest.mock('@helpers', () => ({ lambdaPromise: jest.fn().mockImplementation(() => mockLambdaPromise) })); describe('findUsers', () => { it('should have a main function', async () => { const mockPromise = main(mockEvent); expect(mockPromise).toBeInstanceOf(Promise); expect(mockLambdaPromise).toBeCalledWith(mockEvent, findUsers); }); });
问题原因
Mock逻辑多了一层冗余:lambdaPromise的Mock实现返回的是mockLambdaPromise函数本身,但main里直接调用的是lambdaPromise(event, findUsers),实际需要验证的是**lambdaPromise是否被正确调用**,而非它返回的函数。另外,main是异步函数,未等待其执行完成也可能导致断言时机错误。
修复方案
方案1:直接Mock并验证lambdaPromise的调用
无需额外的mockLambdaPromise,直接给lambdaPromise设置Mock,验证它的调用参数即可:
import { main, findUsers } from '../src/lambdas/user/findUsers'; import { lambdaPromise } from '@helpers'; const mockEvent = { arguments: { userDataQuery: { email: 'johndoe@whatever.com' } } }; // 让lambdaPromise的Mock返回一个已resolve的Promise jest.mock('@helpers', () => ({ lambdaPromise: jest.fn().mockResolvedValue([]) })); describe('findUsers', () => { it('should call lambdaPromise with correct arguments', async () => { await main(mockEvent); // 等待异步函数执行完成 expect(lambdaPromise).toHaveBeenCalledWith(mockEvent, findUsers); expect(main(mockEvent)).toBeInstanceOf(Promise); }); });
方案2:验证返回的Promise结果(可选)
如果需要验证lambdaPromise返回的Promise处理逻辑,可以让Mock返回可控的Promise:
import { main, findUsers } from '../src/lambdas/user/findUsers'; import { lambdaPromise } from '@helpers'; const mockEvent = { arguments: { userDataQuery: { email: 'johndoe@whatever.com' } } }; const mockResolveValue = [{ id: 1, email: 'johndoe@whatever.com' }]; jest.mock('@helpers', () => ({ lambdaPromise: jest.fn().mockResolvedValue(mockResolveValue) })); describe('findUsers', () => { it('should return correct Promise result', async () => { const result = await main(mockEvent); expect(lambdaPromise).toHaveBeenCalledWith(mockEvent, findUsers); expect(result).toEqual(mockResolveValue); expect(main(mockEvent)).toBeInstanceOf(Promise); }); });
关键修复点总结
- 移除多余的
mockLambdaPromise,直接验证lambdaPromise的调用,因为main中直接调用的是该函数 - 调用
await main(mockEvent)确保异步函数执行完成,避免断言时机错误 - 用
mockResolvedValue让Mock返回符合预期的Promise,保证测试逻辑完整
内容的提问来源于stack exchange,提问作者Tamás Polgár
相关产品推荐
相关产品推荐

